Java HashMap 内容 [重复]

Posted

技术标签:

【中文标题】Java HashMap 内容 [重复]【英文标题】:Java HashMap Contents [duplicate] 【发布时间】: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的顺序不同呢?

【问题讨论】:

【参考方案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

【讨论】:

以上是关于Java HashMap 内容 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

JAVA数据结构——Map之HashMap

java并发造成HashMap非线程安全的原因

对java中hashmap深入理解

java在hashmap初始化时赋初值

深度解析HashMap底层实现架构

HashMap(jdk1.8)刨根问底java快速提升