我正在学习 Java 中的容器,最近我读到 HashSet 没有按顺序提供元素。Integer有趣的是我随机制作的 HashSet 被排序了。当我将其类型更改为Double 时,打印的 HashSet 不再排序。我的问题是:那么 HashSet 对各种类型的工作方式是否不同?
你能告诉我为什么下面的代码返回给定未排序数组的集合排序顺序吗?
Stream<Integer> s = Stream.of(2, 3, 1, 4, 5);
Set<Integer> mySet = s.collect(Collectors.toSet());
System.out.println(mySet);
Run Code Online (Sandbox Code Playgroud)
开/关
1, 2, 3, 4, 5
Run Code Online (Sandbox Code Playgroud)
如果我使用 List 而不是 Set,则不会发生这种情况。此外,当输入中有负数时,排序并不总是正确的。是否有任何内置功能可以对 Set 进行排序?
最近我遇到了这个
String s = "9495963";
Set<Character> set = new HashSet<Character>();
for(char e : s.toCharArray()){
set.add(e);
}
System.out.println(set);//[3, 4, 5, 6, 9]
Run Code Online (Sandbox Code Playgroud)
我得到的输出是[3,4,5,6,9],所以,如果HashSet不保留任何顺序,那么为什么这些数字按升序排列?
PS:这个 HashSet 是如何产生排序输出的? 这篇文章没有回答我的问题。我知道如果我将任何数字放入哈希集中,我将不会得到排序顺序。
但是,我发现如果我将所有 [1, 2, 3, ..., n] 放入具有任何混洗顺序的 HashSet 中并迭代 HashSet,我将得到一个guranteed sorted order。我不明白为什么它总是会发生。我已经多次测试过任何 n < 10000 ,它总是正确的,因此这不应该是巧合,应该有一些原因!即使我不应该依赖这个实现细节,请告诉我为什么它总是发生。
PS:我知道如果我将 [0,1,2, ..., n-1] 或 [1+k, 2+k, .., n+k] (k != 0) 插入 HashSet,迭代顺序未排序,我已经测试过。HashSet 的迭代顺序未排序是正常的。但是,为什么 [1,2,3,4,..,n] 的任何插入顺序都意外地总是正确的?我已经检查了实现细节。如果我跟踪路径,整个过程将包括调整桶数组的大小,以及从链表到红黑树的转换。如果我以无序的顺序插入整个 [1-n],则 HashSet 的中间状态是未排序的。但是,如果我完成所有插入,它会意外地排序。
我使用 JDK 1.8 进行了以下测试。
public class Test {
public static void main(String[] args) throws IOException {
List<Integer> res = printUnsortedCase(10000);
System.out.println(res);
}
private static List<Integer> printUnsortedCase(int n){
List<Integer> res = new …Run Code Online (Sandbox Code Playgroud)