Java hashset和treeset

时间:2016-08-03 13:38:53

标签: java hashset treeset

我有一个问题。它说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?

3 个答案:

答案 0 :(得分:3)

根据oracle docs,我们无法保证您会一直获得相同的订单。

  

此类实现Set接口,由哈希表支持   (实际上是一个HashMap实例)。它不能保证   集合的迭代顺序;特别是,它并不保证   订单会随着时间的推移保持不变。

答案 1 :(得分:3)

HashSet不维护顺序,但在打印时必须按某种顺序迭代元素。 HashSetHashMap支持,它按照存储它们的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本身会返回整数,因此,对于单级散列表,它将被排序。