【问题标题】:Hashset ordering issue [duplicate]哈希集排序问题[重复]
【发布时间】:2018-09-18 07:28:30
【问题描述】:

最近遇到了这个

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]

我得到的输出是 [3, 4, 5, 6, 9],那么,如果 HashSet 不保留任何顺序,那么这些数字是如何按升序排列的呢?

【问题讨论】:

  • 迭代哈希集时没有顺序保证。这并不意味着您按顺序查看这些值有任何错误
  • 我知道 LinkedHashSet 保留插入顺序和 TreeSet 重新排列为升序,但如果 HashSet 没有排序,那为什么输出呢?
  • 使用 LinkedHashSet。这维护了插入顺序,TreeSet用于获取插入元素的排序顺序。
  • @kjunz 有 5 个! (120) 5 件事情的安排方式。元素可以以这 120 种方式中的任何一种出现;其中任何一个都同样有效。

标签: java hashset treeset


【解决方案1】:

巧合。碰巧 Character 的 hashCode 是它的数值。如果你不断添加的字符多于 HashSet 中的哈希桶数,你会发现它们乱序了。

【讨论】:

    【解决方案2】:

    HashSet 在内部使用 HashMap

    HashMap 使用每个 Object 的 hashCode() 方法将其元素存储在哈希表中。

    对于 Character 类,hashcode 是它对应的 int 值。

    public static int hashCode(char value) {
        return (int)value;
    }
    

    对于intdouble 数据类型,这些是auto-boxed 进入IntegerDouble 类。当您创建ints 的HashSet 时,它使用Integer's hashCode() 方法,它只返回int。因此,如果您添加 ints,它们将按排序顺序存储。

    但是对于doubleDouble's hashCode() 方法要复杂得多,因为双精度数在内存中的表示方式。

    但是,随着时间的推移,当元素超过存储桶大小时,您会发现它不会保持顺序。

    【讨论】:

      猜你喜欢
      • 2014-04-01
      • 2016-11-21
      • 1970-01-01
      • 2012-03-15
      • 2020-12-21
      • 1970-01-01
      • 2021-10-28
      • 2023-03-27
      • 1970-01-01
      相关资源
      最近更新 更多