Java 为什么我的程序的哈希设置顺序总是相同的?
对于一些教程,他们说: HashSet不维护任何顺序,元素将以任意随机顺序返回 但是我写了一个测试程序,结果总是一样的Java 为什么我的程序的哈希设置顺序总是相同的?,java,hashset,Java,Hashset,对于一些教程,他们说: HashSet不维护任何顺序,元素将以任意随机顺序返回 但是我写了一个测试程序,结果总是一样的 import java.util.*; public class HashSetDemo { public static void main(String[] args) { HashSet<String> hs1 = new HashSet<String>(); hs1.add("a"); h
import java.util.*;
public class HashSetDemo {
public static void main(String[] args) {
HashSet<String> hs1 = new HashSet<String>();
hs1.add("a");
hs1.add("b");
hs1.add("c");
hs1.add("d");
hs1.add(null);
hs1.add(null);
System.out.println(hs1);
System.out.println(hs1);
}
}
我试了很多次,但顺序总是一样的。为什么?希望有人能帮助我,提前谢谢 仅仅因为他们不能保证维持秩序并不意味着他们有时会不守秩序
如果您需要订购,请使用不同的集合-例如treeset。正如我们看到的文档 它不保证集合的迭代顺序;特别是,它不能保证订单在一段时间内保持不变
它可以维持,但不能保证。在添加、删除几次之后,您可以看到差异。当然不是随机顺序,对于某个输入,迭代器的顺序是固定的,我认为他们想说的是顺序可能与输入顺序不同。 实际上,这里的顺序取决于
String.hashCode()
,String.equals()
,以及set.add()
调用的顺序
当您调用
System.out.print(set)
时,您的意思是System.out.print(set.toString())
,并且set.toString()
调用set的迭代器来访问所有元素。这种行为的原因是HashSet
由HashMap
支持,它又由条目
-对象的数组
支持。其中散列
用于查找数组的索引
。因此,在散列集中总是有元素的顺序(数组的顺序),您无法保证这个顺序是什么
从代码中可以看出,HashSet
的顺序是由其元素的计算的hashs
的顺序决定的(或至少受其影响)。然后,对于相对简单的输入(比如您的单个字符串),您可能会假设有一个严格的散列排序
,这将为您提供一个看似自然的排序。对于更复杂的对象,以及因此更复杂的散列
计算,散列
将更分散,排序“更随机”
另外,正如已经指出的,“不保证排序”并不意味着“保证随机排序”
String
类的hashcode
-方法在这里也起作用,对于单个字符String
s,hashcode
将只是字符串中一个char
的int
值。由于char
的int
值是按字母顺序排列的,因此计算出的单个char
字符串的散列也将按字母顺序排列。散列集不会对其进行排序,但它并不意味着必须更改顺序。如果没有添加任何内容,则没有必要更改顺序。例如,看看这个例子
hs1.add("c");
hs1.add("b");
hs1.add("d");
hs1.add("g");
hs1.add(null);
hs1.add(null);
System.out.println(hs1);
输出:[null,b,c,d,g]
然后我们添加一个新元素并再次打印:
hs1.add("a");
System.out.println(hs1);
输出:[null,a,b,c,d,g]
正如你所见,它在一定程度上改变了顺序
没有什么是可以保证的,但这并不意味着它必须改变顺序HashSet
顺序不是随机的,它依赖于实现,实现可以自由更改。JDK 8中有一个显著的变化。因此,如果您升级到Java8,您可能会看到HashMap
顺序发生了变化。如果您使用像IBM这样的非Oracle JDK,情况也可能有所不同。一般来说,您永远不应该依赖它,否则您的程序将来可能会崩溃。HashSet()没有任何顺序。它也不支持输入顺序。但顺序不是随机的。即使您更改了版本并进行了升级,该版本的输出也将更改并保持不变。通过实现您的源代码,我得到了一些不同的答案,如下所示。我已经连续几次执行了这段代码,但输出是相同的
[a、b、c、d、空]
还有一件事,HashSet()不支持重复,因此,添加重复的“null”只会增加代码的长度。HashSet
用于查找可能的重复项,并且必须在对象的哈希(hashCode()
)之后对列表中的对象进行排序才能做到这一点。不会,请尝试,您会看到区别;)在HashMap
类中没有生成随机数,因此这并不令人意外。“无保证顺序”与“保证随机顺序”并不完全相同。
hs1.add("a");
System.out.println(hs1);