如果包含元素被修改,Java HashSet包含重复项

PB_*_*MLT 9 java duplicates hashset

假设您有一个类,并且您创建了一个可以存储此类实例的HashSet.如果您尝试添加相同的实例,则集合中只保留一个实例,这很好.

但是,如果在HashSet中有两个不同的实例,并且您获取一个并使其成为另一个的精确副本(通过复制字段),则HashSet将包含两个重复的实例.

以下代码演示了这一点:

 public static void main(String[] args)
    {
         HashSet<GraphEdge> set = new HashSet<>();
        GraphEdge edge1 = new GraphEdge(1, "a");
        GraphEdge edge2 = new GraphEdge(2, "b");
        GraphEdge edge3 = new GraphEdge(3, "c");

        set.add(edge1);
        set.add(edge2);
        set.add(edge3);

        edge2.setId(1);
        edge2.setName("a");

        for(GraphEdge edge: set)
        {
            System.out.println(edge.toString());
        }

        if(edge2.equals(edge1))
        {
            System.out.println("Equals");
        }
        else
        {
            System.out.println("Not Equals");
        }
    }

    public class GraphEdge
    {
        private int id;
        private String name;

        //Constructor ...

        //Getters & Setters...

        public int hashCode()
        {
        int hash = 7;
        hash = 47 * hash + this.id;
        hash = 47 * hash + Objects.hashCode(this.name);
        return hash;    
        }

        public boolean equals(Object o)
        {
            if(o == this)
            {
                return true;
            }

            if(o instanceof GraphEdge)
            {
                GraphEdge anotherGraphEdge = (GraphEdge) o;
                if(anotherGraphEdge.getId() == this.id && anotherGraphEdge.getName().equals(this.name))
                {
                    return true;
                }
            }

                return false;
        }
    }
Run Code Online (Sandbox Code Playgroud)

上面代码的输出:

1 a
1 a
3 c
Equals
Run Code Online (Sandbox Code Playgroud)

有没有办法强制HashSet验证其内容,以便删除在上面的场景中创建的可能的重复条目?

一种可能的解决方案是创建一个新的HashSet并将内容从一个hashset复制到另一个hashset,这样新的hashset就不会包含重复项,但是我不喜欢这个解决方案.

use*_*421 16

您描述的情况无效.请参阅Javadoc:"如果对象的值以影响等于比较的方式更改,而对象是集合中的元素,则不会指定集合的​​行为."

  • @Spi1988正确的解决方案是坚持"Set"的契约,而不是在将对象添加到集合后修改对象. (4认同)