代码之家  ›  专栏  ›  技术社区  ›  pangpang

为什么我的程序的HashSet顺序总是相同的?

  •  3
  • pangpang  · 技术社区  · 9 年前

    对于一些教程,他们说:

    HashSet不维护任何顺序,元素将以任何随机顺序返回。

    但我写了一个测试程序,结果总是一样的。

    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);
        }
    }
    

    输出:

    [null, a, b, c, d]
    [null, a, b, c, d]
    

    我试了很多次,但顺序总是一样的。为什么?希望有人能帮助我,提前谢谢!

    8 回复  |  直到 9 年前
        1
  •  4
  •   Tobb    9 年前

    这种行为的原因是 HashSet HashMap ,这反过来又由 array 属于 Entry -对象。其中 hash 用于查找 index 大堆 。因此 哈希集 ( 大堆 ),你只是不能保证这个订单是什么。

    据我从代码中所知 哈希集 由计算的 hashes 其元素。然后,对于相对简单的输入(如单个字符串),可以假设 哈希 ,这将给你一个看起来很自然的排序。具有更复杂的对象,因此更复杂 搞砸 计算 哈希 将更加分散,排序“更加随机”。

    此外,正如已经指出的,“不保证有序”并不意味着“保证随机有序”。

    这个 hashcode -方法 String 类也在这里发挥作用,对于单个字符 一串 是的 散列码 将成为 int 一的价值 char 一串 。从那时起 烧焦 整数 值按字母顺序排列,因此计算的 哈希 第页,共页 烧焦 一串 s

        2
  •  1
  •   NimChimpsky    9 年前

    只是因为他们不是 放心 维持秩序并不意味着他们会不正常 有时 .

    如果需要排序,请使用不同的集合,例如树集。

        3
  •  1
  •   Suresh Atta    9 年前

    正如我们看到的文件

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

    它可以维护,但不能保证。在你添加、删除几次之后,你会发现不同之处。

        4
  •  1
  •   nafas    9 年前

    HashSet并不强制它,但这并不意味着它必须更改顺序。如果没有添加任何内容,就没有改变顺序的意义。例如,看看这个例子

    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]

    正如你所看到的,它在某种程度上改变了顺序。

    什么都不能保证,但这并不意味着它必须竭尽全力改变订单

        5
  •  1
  •   mysh    9 年前

    当然不是随机顺序,对于某个输入,迭代器的顺序是固定的,我想他们应该说顺序可能与输入顺序不同。 事实上,这里的顺序取决于 String.hashCode() , String.equals() ,和顺序 set.add() 援引

    当你打电话时 System.out.print(set) ,你是说 System.out.print(set.toString()) set.toString() 调用set的迭代器来访问所有元素。

        6
  •  1
  •   Tagir Valeev    9 年前

    HashSet 顺序不是随机的,它依赖于实现,实现可以自由更改。JDK8中有一个显著的变化 HashMap 更改顺序。如果您使用非Oracle JDK(如IBM),则可能会有所不同。一般来说,你永远不要依赖它,否则你的程序将来可能会崩溃。

        7
  •  0
  •   Samiran Banerjee    8 年前

    HashSet()没有任何排序。它也不支持输入顺序。但顺序不是随机的。即使您更改了版本并进行了升级,输出也将被更改,并保持该版本的输出不变。通过实现源代码,我得到了如下不同的答案。我已经连续多次执行这段代码,但输出是相同的。

    [a,b,c,d,空]

    还有一点,HashSet()不支持重复,因此,添加重复的“null”只会增加代码的长度。

        8
  •  0
  •   larsaars    4 年前

    HashSet 使用 binary search 用于查找可能的重复项,并且必须在列表中的对象的哈希值之后对其进行排序( hashCode() )以便这样做。