添加具有相同的价值观数组HashSet的重复项目结果 [英] Adding arrays with same values to HashSet results in duplicate items

查看:172
本文介绍了添加具有相同的价值观数组HashSet的重复项目结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一组整数数组的,事情是,如果我尝试做的:

I'm trying to create a set of arrays of ints, the thing is that if I try to do:

HashSet<int[]> s = new HashSet<int[]>();
int a1[] = {1,2,3};
int a2[] = {1,2,3};
s.add(a1);
s.add(a2)
System.out.println(s.size());

则S有两个对象,但应该只有一个。
注意:如果是的HashSet&所述不要紧;整数[]>。它只是不工作。

Then s has two objects, but there should be only one. Note: it doesn't matter if it is HashSet< Integer[]>. It just doesn't work.

现在如果我尝试用一​​个ArrayList&LT做到这一点;整数>,是这样的:

Now If I try to do this with an ArrayList< Integer>, something like:

HashSet<ArrayList<Integer>> s = new HashSet<ArrayList<Integer>>();
ArrayList<Integer> a1 = new ArrayList<Integer>();
ArrayList<Integer> a2 = new ArrayList<Integer>();
a1.add(1);
a1.add(2);
a1.add(3);

a2.add(1);
a2.add(2);
a2.add(3);

s.add(a1);
s.add(a2)
System.out.println(s.size());

则S有一个对象。

Then s has one object.

我虽然方式,以避免在第一code中的误差,并存储每个阵列的散列codeS在HashSet的如下:

I though a way to avoid the error in the first code and was storing hashcodes of each array in a hashset as follows:

int a1[] = {0,10083,10084,1,0,1,10083,0,0,0,0};
int a2[] = {1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0,2112};
HashSet<Integer> s= new HashSet<Integer>();//hashcodes of each array
s.add(Arrays.hashCode(a1));
s.add(Arrays.hashCode(a2));
System.out.println(Arrays.hashCode(a1));
System.out.println(Arrays.hashCode(a2));
System.out.println(s.size());

它适用于第一种情况下(1,2,3),但在有冲突它不工作的情况下,所以我必须要管理冲突。所以,我认为我做的是我自己实现HashSet的。

It works for the first case(1,2,3) but in cases where there are collisions it doesn't work, so I would have to manage collisions. So, I think that what I am doing is implementing a HashSet by myself.

使用的HashSet&LT; ArrayList的&LT;整>>它完美。我想了Java在这种情况下管理的冲突。

With HashSet< ArrayList< Integer>> it works perfectly. I suppose that java manage collisions in that case.

我的问题是,为什么Java不允许管理HashSet的&LT; INT []>或HashSet的&LT;整数[]>如果散列codeS生成的相同中的ArrayList&下;阵列的整数>和散列codeS可以通过调用Arrays.hash code(...)来计算。

My question is why java does not allow to manage a HashSet< int[]> or HashSet< Integer[]> if hashcodes generated are the same as in ArrayList< Integer> and hashcodes of arrays can be calculated simply by calling Arrays.hashCode(...).

最后,如果我想要做一个HashSet的&LT; INT []>(或HashSet的&LT;整数[]>)我将不得不由我自己来实现它?或者有更好的方式来做到这一点?

And finally, if I want to do a HashSet< int[]>(or HashSet< Integer[]>) I would have to implement it by myself? Or there is a better way to do it?

感谢。

更新:确定,最后我觉得我已经来到了一个完整的答案。由于@ZiyaoWei和@ user1676075评论这是行不通的,因为等于返回false和散列codeS是型动物​​。但是,为什么java不能覆盖此方法(与满足Arrays.equals(),Arrays.hash code()),所以我们可以做这样的事情的HashSet&LT; INT []>?答案是,因为数组是一个可变的对象,哈希code不能依赖于可变值(数组的每个元素是一个可变值)的哈希值code的总承包合同。 可变对象和哈希code

UPDATE: Ok, finally I think I have came to a complete answer. As @ZiyaoWei and @user1676075 commented it doesn't work because equals returns false and hashcodes are differents. But, why java does not override this methods(with Arrays.equals(), Arrays.hashCode()) so one can do something like HashSet< int[]>? The answer is because an array is a mutable object, and hashcode can not depend on mutable values(each element of array is a mutable value) according to the general contract of hashcode. Mutable objects and hashCode

下面漂亮的哈希code 的说明http://blog.mgm-tp.com/2012/03/hashset-java-puzzler/ 和包含HashMap可变密钥的是可变的HashMap键一种危险的做法?

Here nice explanations of using mutable fields in hashCode http://blog.mgm-tp.com/2012/03/hashset-java-puzzler/ and mutable keys in hashmaps Are mutable hashmap keys a dangerous practice?

我的回答是,如果你想使用的HashSet&LT; INT []>你必须创建一个数组类,如果你想散列code和等于取决于价值观,重写方法equals()和哈希code()以满足Arrays.equals()和Arrays.hash code()。如果你不想违反合同只是使数组决赛。

My answer is, if you want to use a HashSet< int[]> you have to create a class that has an array and if you want that hashcode and equals to depend on values, override methods equals() and hashCode() with Arrays.equals() and Arrays.hashCode(). If you don't want to violate the contract just make the array final.

谢谢大家!

推荐答案

它没有任何在这一天结束时做碰撞:

It has nothing to do with collision at the end of the day:

a1.equals(a2) == false

由于他们是不相等时,设置将它们视为不同的。

请注意阵列在Java中不会覆盖等于方法从对象

Note Array in Java does not override the equals method from Object.

和自添加设置定义为

更正式,将指定的元素e这套如果集合不包含元素E2这样(E == NULL E2 == NULL:e.equals(E2))

More formally, adds the specified element e to this set if the set contains no element e2 such that (e==null ? e2==null : e.equals(e2))

时,似乎是不可能的正确实施设置可能会满足您的要求(比较满足Arrays.equals )在不违反一些合同。

is seems to be impossible to properly implement a Set that might meet your requirement (compare elements with Arrays.equals) without violating some contracts.

这篇关于添加具有相同的价值观数组HashSet的重复项目结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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