我有一个问题。它说java中的hashset并不是一个订单,而是查看我的程序
public static void main(String[] args) {
HashSet<Integer> io=new HashSet<Integer>();
Integer io1=new Integer(4);
Integer io2=new Integer(5);
Integer io3=new Integer(6);
io.add(io2);
io.add(io3);
io.add(io1);
System.out.println(io);
}
并执行它,每次运行它时都会给我一个有序集。为什么会这样?
另一个问题是:如果我实现了一个树集(就像我在之前的程序中所做的那样,而不是使用treeset的hashset和使用我的类的Integer的intead)我必须实现compareto?
答案 0 :(得分:3)
根据oracle docs,我们无法保证您会一直获得相同的订单。
此类实现Set接口,由哈希表支持 (实际上是一个HashMap实例)。它不能保证 集合的迭代顺序;特别是,它并不保证 订单会随着时间的推移保持不变。
答案 1 :(得分:3)
HashSet
不维护顺序,但在打印时必须按某种顺序迭代元素。 HashSet
由HashMap
支持,它按照存储它们的bin的顺序迭代元素。在您的简单示例中,4,5,6被映射到bin 4,5,6(因为整数的hashCode是整数的值)所以它们是按升序打印的。
如果您尝试添加40,50,60,您会看到不同的顺序([50, 40, 60]
),因为默认的初始数量为16,因此哈希码40,50,60将映射到bins 40%16(8),50%16(2),60%16(12),所以50是迭代的第一个元素,接着是50和60。
对于TreeSet<SomeCostumClass>
,您可以在Comparable<SomeCostumClass>
中实施SomeCostumClass
,也可以将Comparator<SomeCostumClass>
传递给构造函数。
答案 2 :(得分:1)
org.bouncycastle.crypto.test.MGF1GeneratorTest
保留内部哈希表(https://en.wikipedia.org/wiki/Hash_table),该表由相应对象HashSet
的结果驱动。对于大多数对象,hashCode()
函数是确定性的,因此迭代相同元素的hashCode()
的结果可能是相同的。这并不意味着它会被订购。但是,对于HashSet
具体而言,函数的Integer
本身会返回整数,因此,对于单级散列表,它将被排序。