Set可以包含重复项吗?

时间:2015-10-08 19:42:00

标签: java set duplicates equals

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

  

注意:如果将可变对象用作set,则必须非常小心   元素。如果a的值,则不指定集合的​​行为   对象以影响等于比较的方式改变   对象是集合中的元素。

结案,谢谢大家!

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

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

我已经使用Java工作了5年多了,并且不笑,但直到现在我才意识到集合的一些东西。我以为我理解了一套是什么,即文档说的是什么:

  

不包含重复元素的集合。更正式的,集合   *不包含e1e2元素对,* e1.equals(e2),最多只有一个null元素。

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

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 + "]";
        }
    }

输出:

  

实体[name = Public,可能会显示:false]实体[name = Public,可能是   显示:真]

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

0 个答案:

没有答案