如果包含的元素被修改,Java HashSet 包含重复项 [英] Java HashSet contains duplicates if contained element is modified

查看:22
本文介绍了如果包含的元素被修改,Java HashSet 包含重复项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Let's say you have a class and you create a HashSet which can store this instances of this class. If you try to add instances which are equal, only one instance is kept in the collection, and that is fine.

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

However if you have two different instances in the HashSet, and you take one and make it an exact copy of the other (by copying the fields), the HashSet will then contain two duplicate instances.

下面是演示这个的代码:

Here is the code which demonstrates this:

 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;
        }
    }

上述代码的输出:

1 a
1 a
3 c
Equals

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

Is there a way to force the HashSet to validate its contents so that possible duplicate entries created as in the above scenario get removed?

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

A possible solution could be to create a new HashSet and copy the contents from one hashset to another so that the new hashset won't contain duplicates however I don't like this solution.

推荐答案

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

The situation you describe is invalid. See the Javadoc: "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."

这篇关于如果包含的元素被修改,Java HashSet 包含重复项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆