【问题标题】:Set by Default Sorted or Not?默认设置是否排序?
【发布时间】:2011-12-02 21:02:34
【问题描述】:

更新

    Set s = new HashSet();
    s.add(1);
    s.add(5);
    s.add(4);
    s.add(9);
    s.add(7);
    s.add(8);        
    s.add("b");
    s.add("a");
    s.add("B");
    s.add("A");
    s.add("s");
    s.add("x");        
    s.add("d");        
    System.out.println(s);
    s.remove("b");
    s.remove("d");
    System.out.println(s);

输出:

[1, d, 4, b, 5, A, B, 7, a, 8, 9, s, x]
[1, 4, 5, A, B, 7, a, 8, 9, s, x]
[1, 4, 5, A, B, 7, a, 8, 9, s, x]

当我们添加时需要一些设置默认排序整数值的信息,但是如果我添加字符串来设置它不会默认排序。

更新: 并且大写字母在运行多次后总是会排序。

java版本“1.6.0_26” Java(TM) SE 运行时环境 (build 1.6.0_26-b03) Java HotSpot(TM) Client VM(build 20.1-b02,混合模式,共享)

请给我一些想法。 谢谢

【问题讨论】:

    标签: java


    【解决方案1】:

    从 Oracle 文档中我们可以发现 HashSet 类实现了 set 接口 并由哈希表内部支持。它不保证集合的迭代顺序;特别是,它不保证订单会随着时间的推移保持不变。 但是下面给出的我的代码发现它即使在运行时间之后也已排序。

     public static void main(String[] args){
            Random rand = new Random(47);           
            SortedSet<Integer> intset = new TreeSet<Integer>();
            Set<Integer> intsetUnsorted = new HashSet<Integer>();
            for(int i=0;i<10000;i++){
                intset.add(rand.nextInt(30));
            }
            intsetUnsorted.add(500);
            for(int i=0;i<10000;i++){
                intsetUnsorted.add(rand.nextInt(30));
            }
            String version = System.getProperty("java.version");
            System.out.println("JDK version-"+version);     
            System.out.println("TreeSet o/p");
            System.out.println(intset);
            System.out.println("Hash Set o/p");
            System.out.println(intsetUnsorted);
    
        }  
    

    O/P

    JDK version-1.6.0
    TreeSet o/p
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
    Hash Set o/p
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 16, 19, 18, 21, 20, 23, 22, 25, 24, 27, 26, 29, 28, 500]
    

    【讨论】:

      【解决方案2】:

      我建议您查看Set interface javaDoc。在 All Known Implementing Classes 部分中,您有提供的实现,如果您检查 HashSet,第一句话就回答了您的问题。

      顺便说一句。检查 javaDoc 始终是一个不错的起点 ;-)

      【讨论】:

      • java 文档说:“..它不保证集合的迭代顺序;特别是,它不保证顺序会随着时间的推移保持不变。这个类允许 null元素...”,我认为(如果我错了,请纠正我)它谈论的是插入顺序而不是排序顺序
      • 它谈论迭代元素。例如,当您将它们打印出来时,您会遍历它们。不知道您所说的“排序顺序”是什么意思。
      【解决方案3】:

      HashSet 不保证其内容会以任何方式排序。对于确实提供这种保证的集合有一个特殊的接口:它称为SortedSet

      一个Set,它进一步提供了对其元素的总排序。这 元素使用其自然顺序或Comparator 进行排序 通常在排序集创建时提供。集合的迭代器 将按元素升序遍历集合。几个额外的 提供操作以利用排序。 (这 接口是SortedMap的集合模拟。)

      在 Java 6 中,有两个类实现了这个接口:ConcurrentSkipListSetTreeSet

      【讨论】:

        【解决方案4】:

        不,HashSet 没有 排序 - 或者至少,不可靠。在某些情况下,您可能碰巧得到订单,但您不能依赖它。例如,它可能总是返回按“哈希码模数素数”排序的条目 - 但不能保证,而且它几乎肯定没有用处。

        如果您需要排序集实现,请查看TreeSet

        【讨论】:

        • 确实,如果你的哈希表被调整大小,顺序会完全改变。 :-)
        • 谢谢,@ChrisJester-Young:当我通过删除“b”、“d”来调整大小时,输出将是相同的
        • @Ravi:这不是我调整哈希表大小的意思。尝试插入足够多的项目以超过哈希图的负载因子,看看会发生什么。
        猜你喜欢
        • 2012-08-24
        • 2013-12-14
        • 2020-01-25
        • 2012-04-05
        • 1970-01-01
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        • 2010-10-09
        相关资源
        最近更新 更多