【问题标题】:Java Sort map by key explanationJava Sort map by key解释
【发布时间】:2018-05-18 21:23:37
【问题描述】:

我最近发现了一种对包含 GregorianCalendar 作为键的地图进行排序的好方法。

Map<GregorianCalendar, String> map = new HashMap<>();

Map<GregorianCalendar, String> sortedMap = map.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
            (oldValue, newValue) -> oldValue, LinkedHashMap::new));

谁能帮我理解这个命令中调用的每个过程,尤其是从流函数中进行的过程?

谢谢

【问题讨论】:

    标签: java sorting java-8 hashmap


    【解决方案1】:

    map.entrySet().stream() 生成输入 Map 的条目的 Stream(即 Stream&lt;Map.Entry&lt;GregorianCalendar,String&gt;&gt;

    .sorted(Map.Entry.comparingByKey()) 通过条目的键对 Stream 的元素进行排序(它依赖于键类型 - GregorianCalendar - 实现 Comparable)。

    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new))

    生成一个LinkedHashMap,其中包含与输入Map 相同的条目。由于您使用的是LinkedHashMap,因此插入顺序保持不变,并且由于您通过键对Stream 的条目进行了排序,因此您将得到一个Map,其插入顺序(和迭代顺序)是根据键。

    当然,您可以通过将输入 Map 的所有条目放入 TreeMap 中来更轻松地获得排序后的 Map

    Map<GregorianCalendar, String> sortedMap = new TreeMap<>(map);
    

    即使您将新条目添加到Map,这也具有保持顺序的优势。

    【讨论】:

    • 谢谢!确实,只要 key 实现 Comparable,TreeMap 似乎是最好的选择。
    • @GeekJunior TreeMap 即使key没有实现Comparable也可以使用,在这种情况下你可以将Comparator传递给构造函数,然后将输入Map传递给@ 987654344@
    【解决方案2】:

    首先你通过Key通过sorted(Map.Entry.comparingByKey())对条目进行排序

    然后这些被收集到Map(下面的实现使用HashMap),其中Key 的类型为GregorianCalendar,值的类型为String。该代码还提供了一个合并功能:

    (oldValue, newValue) -> oldValue
    

    当发生冲突时,它们保留最后一个值的位置,例如“最后获胜”策略。因此,当这些是冲突时(两个相同的 GregorianCalendar 值),您将始终保留第二个,无论第二个在这里意味着什么。由于您的流式传输源是没有定义顺序的HashMap,因此如果您在初始映射中添加或删除值,则此“第二个”可能会发生变化。

    一旦对它们进行排序并将它们收集到 HashMap(通过 collect),您的订单可能会中断,因此收集发生在 LinkedHashMap 中,基本上保留了排序顺序

    【讨论】:

      【解决方案3】:

      我只想为这种排序留下一个通用方法,因为这对我来说有点棘手

      private <K extends Comparable<? super K>,V> Map<K, V> sortMapByKey(Map<K, V> map) {
      
              return  map.entrySet().stream()
                      .sorted(Map.Entry.comparingByKey())
                      .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue,
                              LinkedHashMap::new));
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-19
        • 1970-01-01
        • 1970-01-01
        • 2018-08-18
        • 2014-08-31
        • 2013-01-16
        • 2012-11-22
        • 1970-01-01
        相关资源
        最近更新 更多