我希望在TreeSet中有一些int对,并按第一个数字排序。
代码test here:
public static void main (String[] args) throws java.lang.Exception
{
SortedSet<int[]> s = new TreeSet<int[]>(new Comparator<int[]>(){
public int compare(int[] a, int[] b) {
return b[0] - a[0];
}
});
int[] a = new int[]{1, 2};
int[] b = new int[]{1, 3};
s.add(a);
s.add(b);
System.out.println(s.size());
}
我不知道为什么TreeSet的大小变成1.看起来像a
和b
的hashCode是相同的,但为什么呢?
感谢您的帮助。
BTW:实际上,我试图将重复的数字放在一个集合中,这是不可能的。然后我尝试在一组中使用int对。第一个数字是我想要的实际数字,第二个数字是为了防止重复。但我遇到了这个问题。答案 0 :(得分:5)
结果是1
,因为您的compare
方法仅使用数组中的第一个数字,而您拥有的两个数组都以1
开头。因此,从TreeSet
的角度来看,两个数组是相同的。
如果此集合尚未包含指定的元素
,则为true
,由于这两个值被视为相等(compare
返回0
),因此未添加第二个值,add()
返回false
答案 1 :(得分:3)
认为哈希码在基于树的数据结构中起作用是一个常见的错误,它实际上并不存在。基于哈希的集合(HashSet,LinkedHashSet,HashMap,LinkedHashMap
和其他几个)使用散列和等于区分对象。
在你的情况下,一个TreeSet,你使用一个基于数组大小长度考虑相等性的比较器来处理对象相等。如果两个数组具有相同的大小,它会考虑相等。在你的情况下,数组b替换数组a在头节点中,因为两个数组的长度都是1.即使覆盖hashcode
,它也不会有任何用处。
来自JavaDocs: -
请注意,如果要正确实现Set接口,则由set维护的排序(无论是否提供显式比较器)必须与equals一致。 (有关与equals一致的精确定义,请参阅Comparable或Comparator。)这是因为Set接口是根据equals操作定义的,但TreeSet实例使用compareTo(或compare)方法执行所有元素比较,因此从集合的角度来看,通过这种方法被认为相等的元素是相等的。集合的行为即使其排序与equals不一致也是明确定义的;它只是不遵守Set接口的一般合同。