【问题标题】:Why does a HashSet sort single alphabetic characters?为什么 HashSet 对单个字母字符进行排序?
【发布时间】:2018-11-20 20:49:13
【问题描述】:

所以我知道 HashSet 没有像 SortedSet 这样的真正排序功能,但是我偶然发现了这一点:

当我运行以下代码时:

 public static void main(String[] args) {
    Set<String> collection = new HashSet<String>(2000);
    String[] data = {"a", "c", "g", "f", "b", "f", "b", "d","q","r","d","m"};
    for(String input: data)
    {
        collection.add(input);
    }
    System.out.println("Output: " + collection);
}

我得到以下输出: 输出:[a, b, c, d, f, g, m, q, r]

这是按字母顺序排序的。这是为什么?因为 HashSet 不是排序集。

所以我尝试使用一串字符而不是单个字符:

public static void main(String[] args) {
    Set<String> collection = new HashSet<String>(2000);
    String[] data = {"atjre", "crj", "gertj", "fertj", "berj"};
    for(String input: data)
    {
        collection.add(input);
    }
    System.out.println("Output: " + collection);
}

我得到以下输出:输出:[crj,atjre,fertj,gertj,berj]

现在它们不再排序,对此有何解释?或者这只是一个偶然的巧合?

【问题讨论】:

  • HashSet是基于hashcodes实现的。
  • 也就是说,由于数据在 hashSet 中的存储方式(使用equals()hashCode()),这样,当比较'a''g' 时,'a' 总是更小等等,因此它被排序
  • How to sort a HashSet?的可能重复

标签: java set hashset


【解决方案1】:

HashSet 实现Set 接口。这意味着不保证元素的顺序。

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

随着时间的推移,你添加,删除几次你会看到不同。

但是,“不保证排序”并不意味着“保证随机排序”。您的问题的确切答案是,

String 类的hashcode-方法也在这里发挥作用, 对于单个字符 Strings,hashcode 将只是 int Stringchar 的值。因为charint 值按字母顺序排列,计算出的hashes 也将按字母顺序排列 单charStrings.

【讨论】:

    【解决方案2】:

    根据 Java 文档:https://docs.oracle.com/javase/7/docs/api/java/util/HashSet.html

    它不保证集合的迭代顺序;特别是,它不保证订单会随着时间的推移保持不变。

    我认为您在这里遇到的是哈希函数分布异常。散列函数在内部用于为您的字符串提供整数索引。对于 1 长的字符串,没有太多复杂性。随着您的字符串变长,您的哈希函数可以使用更多。

    这可以追溯到散列函数的整个想法:获取一组可能的值,并将它们尽可能均匀地映射到一组更小的值。碰巧散列函数将这些字符串按原样映射。您可能会看到连续数字相同的情况。一旦引入更多数据,您就会开始看到它们是无序的。

    【讨论】:

      猜你喜欢
      • 2012-07-12
      • 2017-12-03
      • 2013-06-05
      • 1970-01-01
      • 1970-01-01
      • 2022-06-12
      • 2017-10-04
      • 2021-09-19
      • 2021-09-17
      相关资源
      最近更新 更多