【问题标题】:elements of HashMap are in the wrong order [duplicate]HashMap 的元素顺序错误[重复]
【发布时间】:2013-05-27 15:04:09
【问题描述】:

我需要从文件中读取两列(均为字符串),并将第一列的值保存在 HashMap 中,其中 Integer 是计数器。

例如,如果我正在阅读的文件是

Apple Fruit
PC    Device
Pen   Tool
...

代码是

    String line="";
    int counter=1;
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("test.txt"),"Unicode"));
    while ((line = reader.readLine()) != null)
    {
        String[] words;
        words= st.split(" ");
            tokens.put(counter, words[0]);
        counter+=1;
    }

问题是当我打印 HashMap 值时,我发现这些值的顺序与原始文件中的顺序不同

        for (Map.Entry<Integer, String> token:tokens.entrySet())
    {
        System.out.println(token.getKey() + token.getValue());
    }

我得到了以下

1   Apple
3   Pen
4   whatever
2   ..etc

不知道是什么问题?!你能帮帮我吗

【问题讨论】:

  • 您将需要使用不同的容器。 hashmap 实现的本质几乎保证了原始顺序不会被保留。
  • 你认为这里的正确顺序是什么?
  • 取决于密钥!

标签: java hashmap


【解决方案1】:

正如文档明确指出的那样,HashMap 是无序的
枚举顺序由键的hascode决定。

如果您想在枚举地图时保留插入顺序,请使用LinkedHashMap
如果您希望枚举顺序遵循键的自然顺序,请使用TreeMap

【讨论】:

  • 好的,HashMap中元素的排序依据是什么?为什么这个命令!!!!为什么 4 在 2 之前出现
  • @Wahedsaw:它基于哈希码。 en.wikipedia.org/wiki/Hashtable
  • @Wahedsaw 元素的顺序基于键的哈希码值。查看[here] 了解更多关于 HashMap 的详细信息。
  • @Wahedsaw 您看到的顺序是键的哈希的标准排序。
  • A HashMap 将其数据存储在一组称为存储桶的列表中。当您添加一个键值对时,映射调用key.hashCode(),将它取模于存储桶的数量,并将其放入该编号的存储桶中。当桶变得太大时,地图会创建更多的桶,并调整地图中的所有对。这就是为什么在迭代地图时不能改变地图的原因之一。如您所见,桶的顺序和每个桶中的项目会随着时间而变化。由于模块化减少,甚至哈希码都没有对项目进行排序。
【解决方案2】:

HashMap 未排序。您无法控制项目的显示顺序。如果您想要一个有序的地图,您可以使用,例如,TreeMap

编辑:感谢提出这个问题的人:TreeMap 将使项目保持自然排序顺序(即在您的情况下按字母顺序排列)。 LinkedHashMap 将保留插入顺序。

【讨论】:

  • 但这将使用自然排序或需要比较器。我建议LinkedHashMap 用于广告订单。
  • @PaulBellora 公平竞争。这就是为什么我说例如 TreeMap。 OP 没有具体说明他/她在寻找什么订单。
【解决方案3】:

如果您想要返回插入顺序,请使用 LinkedHashMap 。默认情况下,HashMap 的迭代器不保证插入顺序。

【讨论】:

    【解决方案4】:

    HashMap 不是有序的Collection。 (它甚至不是Collection)它更像是一本字典。

    如果您想保持项目的顺序,您可以使用TreeMapLinkedHashMap

    它们之间的区别在于TreeMap 保持它们的自然排序顺序,而LinkedHashMap 保持插入顺序。

    在大多数情况下,如果您希望使用List 来实现类似功能,您可以使用LinkedHashMap

    TreeMap 内部实现使用红黑树,而LinkedHashMap 使用双向链表。

    我的建议是参考官方documentation。在那里你会找到详尽的解释。

    另外,迭代Maps 的惯用方式是这样的:

    for(Integer key : map.keySet()) {
        String myString = map.get(key);
        // ...
    }
    

    【讨论】:

      猜你喜欢
      • 2016-08-10
      • 2015-04-25
      • 2016-06-05
      • 2015-06-22
      • 1970-01-01
      • 2016-07-25
      • 2013-10-10
      • 2020-01-06
      • 2021-07-16
      相关资源
      最近更新 更多