繁体   English   中英

不向超级类列表添加任何重复项(检查子类是否相等)

[英]Add no duplicates to List of supperclass (check for equality with subclasses)

我有一个List<Item> items = new ArrayList<>(); 我将两个不同的Item添加到Item两个子类: PortableItemSceneryItem

public class Item implements Comparable<item> {
    public String id;
    public String desc;

    ...

    public int compareTo(Item o) {
        return getId().compareTo(o.getId());
    }  
}

现在,我想在将新ID添加到列表之前检测ID的项目。

    PortableItem a = new PortableItem("a");
    SceneryItem b  = new SceneryItem("a");
    items.add(a);
    items.contains(b); 

返回false。 我该如何改变这种行为?

您可以添加一个与id进行比较的equals方法,默​​认情况下,当Object ==时, Object等于另一个-即同一实例。 这不是你想要的。

public class Item implements Comparable<Item> {

    public String id;
    public String desc;

    public String getId() {
        return id;
    }

    @Override
    public int compareTo(Item o) {
        return getId().compareTo(o.getId());
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 17 * hash + Objects.hashCode(this.id);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof Item)) {
            return false;
        }
        final Item other = (Item) obj;
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        return true;
    }
}

无论如何,给定您的compareTo方法和与equals一致的要求,这确实是一个好习惯-现在a.equals(b)如果具有相同的id则将返回true。

当您现在拥有一个equals方法时,您必须具有一个hashCode()方法,这也是与equals要求一致的方法。

请注意,如果您在超类中覆盖equals方法,那么除非您使用调用最后return super.equals ,否则这显然将不起作用。

现在,使用List可以确保contains方法O(n)-这非常慢 我建议使用一个contains保证为O(1)的Set 如果您需要维护订单,请使用LinkedHashSet或更好的TreeSet ,它将使用您的compareTo方法自动订购商品。

无论如何,您总是可以事后通过一个O(n)调用将其转换为List

您需要重写基类中的equals()hashCode()方法以按ID进行比较。
compareTo()仅用于排序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM