Java 哈希集和树集
Java hashset and 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);
}
并执行它,每次我 运行 它都会给我一个有序集。为什么会这样?
另一个问题是:如果我实现一个树集(就像我在之前的程序中所做的那样,而不是使用树集的哈希集和使用我的 class 的 Integer 的 intead)我必须实现 compareto 吗?
根据oracle docs,无法保证您会一直收到相同的订单。
This class implements the Set interface, backed by a hash table
(actually a HashMap instance). It makes no guarantees as to the
iteration order of the set; in particular, it does not guarantee that
the order will remain constant over time.
HashSet
不保持顺序,但它必须在打印元素时按某种顺序遍历元素。 HashSet
由 HashMap
支持,它按照存储元素的 bin 的顺序遍历元素。在您的简单示例中,4、5、6 映射到 bin 4、5、6(因为整数的 hashCode 是整数的值)所以它们按升序打印。
如果您尝试添加 40、50、60,您会看到不同的顺序 ([50, 40, 60]
),因为默认的初始 bin 数量是 16,所以哈希码 40、50、60 将是映射到 bins 40%16 (8),50%16 (2) ,60%16 (12),所以 50 是迭代的第一个元素,然后是 50 和 60。
至于 TreeSet<SomeCostumClass>
,您可以在 SomeCostumClass
中实现 Comparable<SomeCostumClass>
,或者将 Comparator<SomeCostumClass>
传递给构造函数。
A HashSet
保留一个内部散列 table (https://en.wikipedia.org/wiki/Hash_table),它由各个对象 hashCode()
的结果驱动。对于大多数对象,hashCode()
函数是确定性的,因此对相同元素迭代 HashSet
的结果可能是相同的。这并不意味着它将被订购。但是,对于 Integer
具体而言,函数 returns 的 hashCode()
本身就是整数,因此,对于单级散列 table 它将被排序。
我有一个问题。它说 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);
}
并执行它,每次我 运行 它都会给我一个有序集。为什么会这样?
另一个问题是:如果我实现一个树集(就像我在之前的程序中所做的那样,而不是使用树集的哈希集和使用我的 class 的 Integer 的 intead)我必须实现 compareto 吗?
根据oracle docs,无法保证您会一直收到相同的订单。
This class implements the Set interface, backed by a hash table (actually a HashMap instance). It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time.
HashSet
不保持顺序,但它必须在打印元素时按某种顺序遍历元素。 HashSet
由 HashMap
支持,它按照存储元素的 bin 的顺序遍历元素。在您的简单示例中,4、5、6 映射到 bin 4、5、6(因为整数的 hashCode 是整数的值)所以它们按升序打印。
如果您尝试添加 40、50、60,您会看到不同的顺序 ([50, 40, 60]
),因为默认的初始 bin 数量是 16,所以哈希码 40、50、60 将是映射到 bins 40%16 (8),50%16 (2) ,60%16 (12),所以 50 是迭代的第一个元素,然后是 50 和 60。
至于 TreeSet<SomeCostumClass>
,您可以在 SomeCostumClass
中实现 Comparable<SomeCostumClass>
,或者将 Comparator<SomeCostumClass>
传递给构造函数。
A HashSet
保留一个内部散列 table (https://en.wikipedia.org/wiki/Hash_table),它由各个对象 hashCode()
的结果驱动。对于大多数对象,hashCode()
函数是确定性的,因此对相同元素迭代 HashSet
的结果可能是相同的。这并不意味着它将被订购。但是,对于 Integer
具体而言,函数 returns 的 hashCode()
本身就是整数,因此,对于单级散列 table 它将被排序。