java - 不向 super 类列表添加重复项(检查与子类是否相等)

标签 java inheritance comparison

我有一个List<Item> items = new ArrayList<>();我将两个不同的项目添加到 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 的项目在将新列表添加到我的列表之前。

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

返回错误。我怎样才能改变这种行为?

最佳答案

您可以添加一个equals方法来比较id,默认情况下,当它们==时,一个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 要求。

请注意,如果您在父类(super class)中重写了 equals 方法,那么这显然不会起作用,除非您在最后调用 return super.equals

现在,使用 Listcontains 方法可以保证 O(n) - 这非常慢。我建议使用 Set ,其中 contains 保证为 O(1)。如果您需要维护顺序,请使用 LinkedHashSet 甚至更好的 TreeSet ,它将使用您的 compareTo 方法自动对项目进行排序。

之后你总是可以通过一次 O(n) 调用将其转换为 List...

关于java - 不向 super 类列表添加重复项(检查与子类是否相等),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15417492/

相关文章:

Java:如何从 Oracle DB 表解析 XML 类型列数据?

java - 在hadoop中使用java系统属性

Java:组件中的 setPreferredSize() 和 setSize() 方法之间的区别

java - 最小的epsilon使得比较结果改变

java - 从 Android Java 进程中获取或创建上下文

c# - 使用继承的构建器模式

c++ - 有没有办法避免在特定的自定义类继承结构中使用虚拟方法?

c++ - AlmostEqual2sComplement 实现不处理退化的情况

c++ - 如何比较 char 或 string 变量是否等于某个字符串?

c# - 如何调用 == 运算符来调用 child 的实现?