java – Set可以包含重复项吗?

更新:答案实际上在文档中:

Note: Great care must be exercised if mutable objects are used as set
elements. The behavior of a set is not specified if the value of an
object is changed in a manner that affects equals comparisons while
the object is an element in the set.

案件结案,谢谢大家!

编辑:关于散列集中重复项的引用主题确实有相同的观点,但是它没有回答我的问题:为什么文档没有说任何关于集合只能用于处理不可变对象?

edit2:我明白会发生什么.该组当然无法知道实体的哈希码何时在添加后发生变化.但问题是,文档应该清楚地说明set只能与不可变对象一起正常工作.

我已经用Java工作了5年多了,不要笑,但只是现在我才意识到套装的一些东西.我以为我理解了一套是什么,即文档说的是什么:

A collection that contains no duplicate elements. More formally, sets
* contain no pair of elements e1 and e2 such that * e1.equals(e2), and at most one null element.

但是,这完全不正确?!看这里:

public static void main(String[] args) {

        Set<Entity> entitySet = new HashSet<>();
        Entity e1 = new Entity("One");
        Entity e2 = new Entity("Two");
        entitySet.add(e1);
        entitySet.add(e2);

        e2.name = "One"; // !
        System.out.println("Objects equal:" + e1.equals(e2));

        Iterator<Entity> iterator = entitySet.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }

    static class Entity {

        String name;

        Entity(String name) {
            this.name = name;
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof Entity)) {
                return false;
            }
            return name.equals(((Entity) obj).name);
        }

        @Override
        public int hashCode() {
            return name.hashCode();
        }

        @Override
        public String toString() {
            return "Entity[name=" + name + "]";
        }

输出:

Objects equal:true
Entity[name=One]
Entity[name=One]

所以,我猜关于不​​包含重复项的集合的事情只有在我们处理不可变条目时才是真的吗?但为什么文件没有说什么呢?我从来没有真正意识到这一点.当然,问题在于,entites可能包含任何不属于等式定义的其他字段;他们在这些领域可能会有所不同.我在考虑这样的事情:

 public static void main(String[] args) {

        Set<Entity> entitySet = new HashSet<>();
        Entity e1 = new Entity("Public", true);
        Entity e2 = new Entity("Secret", false);
        entitySet.add(e1);
        entitySet.add(e2);
        e2.name = "Public";

        Iterator<Entity> iterator = entitySet.iterator();
        // print only public entity (e1)
        while (iterator.hasNext()) {
            Entity e = iterator.next();
            if (e.equals(e1)) { 
                System.out.println(e);
            }
        }
    }

    static class Entity {

        String name;
        boolean mayBeDisplayedToUser;

        Entity(String name, boolean mayBeDisplayedToUser) {
            this.name = name;
            this.mayBeDisplayedToUser = mayBeDisplayedToUser;
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof Entity)) {
                return false;
            }
            return name.equals(((Entity) obj).name);
        }

        @Override
        public int hashCode() {
            return name.hashCode();
        }

        @Override
        public String toString() {
            return "Entity[name=" + name + ", may be displayed:" + mayBeDisplayedToUser + "]";
        }
    }

输出:

Entity[name=Public, may be displayed:false] Entity[name=Public, may be
displayed:true]

所以..我现在很困惑.我是唯一一个不知道这一点的人吗?

解决方法:

您将这些项添加到HashSet中,因为它们是唯一的,然后在事后变更项.包含HashSet不知道您通过更改obj.name来破坏集合约.

上一篇:python – 删除列表中的重复数据帧


下一篇:比较并从java中的2个数组中提取类似的字符串,不重复