【问题标题】:Java HashMap Contents [duplicate]Java HashMap 内容 [重复]
【发布时间】:2018-01-02 13:53:58
【问题描述】:

我有一个 HashMap 来存储我的 <Integer, ArrayList<String>> 数据。如果地图尚不存在,我使用put(...) 在地图中添加数据。我使用containsKey() 检查条目是否 Key 已在地图中。如果它存在,我通过这样做将字符串添加到键中:

x.get(i).add(str)

为了获取数据,我只是用哈希的keySet() 进行了一个 for 循环。

如果我有这个哈希:

int -> array of strings
1 -> "a", "b", "c"
2 -> "aa", "bb", "cc"
3 -> "aaa", "bbb", "ccc"

我的问题是,读取的数据顺序不一致。 在 1 台 PC 中,它可能按以下顺序读取密钥:2、1、3。在另一台 PC 中,它可能按以下顺序读取密钥:1、2、3。

我希望它们的读取顺序在所有 PC 上都相同。它们进入hashmap的顺序也是一样的,但是为什么hashmap读取Keyset的顺序不同呢?

【问题讨论】:

    标签: java hash hashmap


    【解决方案1】:

    您是否阅读过HashMap 的Javadoc?它不保证订购。

    这个类不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。

    如果您想要一致的排序,请使用LinkedHashMapTreeMapHashMap 缺乏保证意味着,如果 Java 开发人员选择,它可以在星期二向后迭代。

    【讨论】:

    • 为了扩展答案,LinkedHashSet 包含一个LinkedList 和一个HashSet,以便记住排序这当然会增加开销(每个条目两个额外的指针)。默认情况下,HashSet 的概念不允许持有任何订单,请参阅Wikipedia 了解其工作原理。
    • 呃,不完全是。没有LinkedList 对象,只是修改了映射的条目,也形成了一个链表。
    • 是的,我就是这个意思。突出显示可能有点误导,对此感到抱歉。只是Entry<K, V>还有一个previous和一个next指针,组成一个链表,如你所说。
    【解决方案2】:

    其实没有办法控制Hash Map中元素的输入顺序,但是可以在处理之前先排序。

    public class HashMapSample {
        public static void main(String[] args) {
            Map<Integer,List<String>> myHash = new HashMap<>();
            myHash.put(1, Arrays.asList("a","aa","aaa"));
            myHash.put(3, Arrays.asList("c","ccc","ccc"));
            myHash.put(2, Arrays.asList("b","bb","bbb"));
            System.out.println(myHash);
            myHash.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey)).forEach(System.out::println);
    
        }
    }
    

    【讨论】:

    • 这也是一个不错的主意,但最好只使用一个保持顺序的集合实现,因为排序会增加巨大的性能开销。
    • 我非常同意你的看法。这将取决于问题的上下文以及必须解决的需求类型。问候。
    【解决方案3】:

    你需要使用 TreeMap 而不是 HashMap

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-17
      • 1970-01-01
      • 2015-08-28
      • 2020-11-30
      • 2013-03-04
      • 2011-12-24
      • 1970-01-01
      • 2015-02-05
      相关资源
      最近更新 更多