2

我有字符串数组,实际上只是来自文件的整数列表。我将其转换为 HashSet 以删除重复项,如下所示:

Set<String> intSet = new HashSet<String>(Arrays.asList(strArr));

我希望所有数字都按顺序排列,但当然,因为这是一个字符串而不是整数列表,它可能不按顺序排列。但是每当我尝试打印这个 HashSet 时,我总是得到如下输出:

[3, 2, 1, 4]
[3, 2, 5, 4]

每次,如果存在 3,则将其视为第一个元素。我不明白为什么它会这样?谁能给我解释一下。

4

4 回答 4

9

HashSet不保持可预测的顺序,它将取决于hashCode对象引用的。如果要保持插入元素的顺序,请使用LinkedHashSet. 如果要保持元素始终排序,请使用TreeSet.

于 2013-05-24T14:22:57.427 回答
9

返回的顺序取决于内部散列算法,您应该对此无动于衷。(散列算法背后的想法是在一个内部表中均匀地分散键值。你可能每次都得到 3,因为这个算法可能是确定性的)。

如果您希望按字典顺序返回,请使用 TreeSet。

要保留插入顺序,请使用 LinkedHashSet。

于 2013-05-24T14:24:55.360 回答
2

这是由于 HashSet 的实现。如果你想要一个维持某种顺序的 Set,你可以使用 LinkedHashSet 代替。

从 LinkedHashSet javadoc:

此实现使其客户免于 HashSet 提供的未指定、通常混乱的排序,而不会增加与 TreeSet 相关的成本。它可用于生成与原始集合具有相同顺序的集合的副本,而不管原始集合的实现如何:

于 2013-05-24T14:26:22.937 回答
0

从 Oracle 文档中我们可以发现 HashSet 类实现了 set 接口,并在内部由 Hash Table 支持。它不保证 set 的迭代顺序;特别是,它不保证订单会随着时间的推移保持不变。

因此,如果您关心元素的顺序,我会建议您使用 TreeSet。

public static void main(String[] args){
        String version = System.getProperty("java.version");
        System.out.println("JDK version-"+version); 
        SortedSet<String> ss = new TreeSet<String>();
        ss.add("1");
        ss.add("3");
        ss.add("2");
        ss.add("4");
        System.out.println(ss);

    }

o/p:

JDK version-1.6.0
[1, 2, 3, 4]
于 2018-04-18T09:00:14.300 回答