使用HashSet的唯一对象列表

时间:2017-09-17 17:10:30

标签: java hashset

有谁能告诉我我的代码存在什么问题?我将代码从this post转换为使用String数组而不是两个整数,其中我想要一个基于String数组的第0个索引的唯一列表。问题是被覆盖的equals函数永远不会被调用,因此我重复了一些条目。

public static void main(String[] args) 
{
        class bin
        {
                String[] data;

                bin (String[] data)
                {
                    this.data=data;
                }

                @Override
                public boolean equals(Object me) 
                {
                    bin binMe = (bin)me;
                    if(this.data[0].equals(binMe.data[0])) { return true; }
                    else { return false; }
                }   

                @Override
                public int hashCode() 
                {
                    final int prime = 31;
                    int result = 1;
                    result = prime * result + Arrays.hashCode(data);
                    return result;              
                }

                @Override
                public String toString() 
                {
                    return data[0] + " " + data[1];
                }
        }

        Set<bin> q= new HashSet<bin>();
        q.add(new bin(new String[]{"100", "200"}));
        q.add(new bin(new String[]{"101", "201"}));
        q.add(new bin(new String[]{"101", "202"}));
        q.add(new bin(new String[]{"103", "203"}));

        System.out.println(q);
}

输出:[101 202,100 200,101 201,103 203]

3 个答案:

答案 0 :(得分:2)

如果您希望基于第一个元素进行比较,请不要使用完整数组的哈希码

Arrays.hashCode(data);

使用

data[0].hashCode();

答案 1 :(得分:2)

  

问题是被覆盖的equals函数永远不会得到   因此,我重复了参赛作品。

这是不正确的。它确实被调用了。但是,只有两个集合元素都被认为是相等的,equals方法返回true,hashCode返回相同的int。在您的情况下,您已经覆盖了equals方法,以根据字符串数组的第一个元素进行逻辑比较。但是,您需要确保hashCode还为您认为在逻辑上相等的两个元素返回相同的int

因此,请在hashCode实施

中更新以下声明

result = prime * result + Arrays.hashCode(data);

result = prime * result + data[0].hashCode();

答案 2 :(得分:1)

Hash [Set / Map]的工作方式是使用hashCode将项目分组到列表中,然后搜索这些列表,这意味着如果所有hashCodes都是唯一的,那么列表只是1个项目,它加快了项目的查找速度。

如果你的hashCode指向错误的列表,则没有项目要检查是否相等,所以从不调用equals方法,并且每个项目都被添加,而不仅仅是唯一的项目。

不是在整个字符串数组上计算hashCode,而是使用data[0].hashCode();,根据@ cricket_007的答案