哈希映射输出键的升序

时间:2018-02-01 10:48:54

标签: java

我们观察到下面提到的使用哈希映射的程序仍然按键的升序给出输出。

import java.util.Map;

import java.util.Set;

import java.util.TreeMap;

public class SampleProgram {
    public static void main(String[] args) {
        HashMap<Integer, String> hmap = new HashMap<Integer, String>();
        hmap.put(100, "A");
        hmap.put(107, "C");
        hmap.put(101, "Z");
        hmap.put(106, "Y");
        hmap.put(104, "P");
        hmap.put(105, "Q");
        hmap.put(108, "R");
        Set set = hmap.entrySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Map.Entry me = (Map.Entry) iterator.next();
            System.out.print(me.getKey() + ": ");
            System.out.println(me.getValue());
        }
    }
}

正如我在java文档中读到的那样,哈希映射不会返回任何顺序。但是我们观察到在上面提到的程序中它正在对键进行排序并返回输出。但同时我们使用以下数据集来交叉验证它没有排序的时间。那么,原因是什么?

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class SampleProgram {
public static void main(String[] args) {
        HashMap<Integer, String> hmap = new HashMap<Integer, String>();
        hmap.put(30, "A");
        hmap.put(5, "C");
        hmap.put(76, "Z");
        hmap.put(100, "Y");
        hmap.put(90, "P");
        hmap.put(34, "Q");
        hmap.put(23, "R");
        Set set = hmap.entrySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Map.Entry me = (Map.Entry) iterator.next();
            System.out.print(me.getKey() + ": ");
            System.out.println(me.getValue());
        }
    }
}

2 个答案:

答案 0 :(得分:1)

如果您想维护条目的顺序,则应使用LinkedHashMap代替。 来自Javadoc:

  

使用Hash表和Map接口的链表实现   可预测的迭代顺序。此实现与HashMap不同   因为它维护着一个贯穿所有链接的双向链表   条目。该链表定义了迭代排序,即   通常是键插入地图的顺序   (插入顺序)。

要理解为什么在您的特定情况entrySet似乎&#34;排序&#34;条目,让我们看看hash table data structure是如何运作的。

因此存在一系列桶,初始大小为16(在HashMap实现的情况下)。 bucket的条目索引由简单的公式确定:key_hash_code % buckets_array_size

让我们看一下你的例子,找出放入哪些桶条目。

第一段代码:

Integer.hashCode(100) % 16 = 4
Integer.hashCode(107) % 16 = 11
Integer.hashCode(101) % 16 = 5
Integer.hashCode(106) % 16 = 10
Integer.hashCode(104) % 16 = 8
Integer.hashCode(105) % 16 = 9
Integer.hashCode(108) % 16 = 12

第二段代码:

Integer.hashCode(30) % 16 = 14
Integer.hashCode(5) % 16 = 5
Integer.hashCode(76) % 16 = 12
Integer.hashCode(100) % 16 = 4
Integer.hashCode(90) % 16 = 10
Integer.hashCode(34) % 16 = 2
Integer.hashCode(23) % 16 = 7

这样就可以清楚地解释为什么条目会以有序的方式打印在您的第一个代码段中,而不是第二个。

答案 1 :(得分:0)

您用于迭代的entrySet()方法会返回地图内映射的设置视图

套件和HashMaps对订单无保证。特别是,不保证订单将保持不变

如果您想要对HashMap的元素进行排序,您可以使用以下步骤:

Set hmap = new HashSet();

...

List sortedList = new ArrayList(hmap);
Collections.sort(sortedList);