【问题标题】:Sort a Map<Long, ZonedDateTime> by date in order to find max and min按日期对 Map<Long, ZonedDateTime> 进行排序以找到最大值和最小值
【发布时间】:2022-01-24 06:15:05
【问题描述】:

我有一个格式为 HashMap 的哈希映射。 例如,

[(100, 01/01/2018 - 13:45:30 +0000),
 (101, 02/05/2018 - 13:45:30 +0000), 
(102, 02/01/2012 - 13:45:30 +0000)].

我想要这个输出:

 (102, 02/01/2012 - 13:45:30 +0000)
 (100, 01/01/2018 - 13:45:30 +0000)
 (101, 02/05/2018 - 13:45:30 +0000)

【问题讨论】:

  • 您应该使用 OffsetDateTime 类作为此类值,而不是 ZonedDateTime。您的输入带有与 UTC 的偏移量,而不是时区。

标签: java hashmap zoneddatetime


【解决方案1】:

您无法对 HashMap 进行排序,因为它始终以随机顺序存储值并提供随机访问。

您需要使用LinkedHashMap - 插入的值与 HashMap 相同,但在链表中保持顺序。

LinkedHashMap方式:

  1. 照常插入。
  2. Collections.sort(dateComparator)
  3. 照常阅读。

下一部分是定义比较器。下面是一个比较器的示例,它按其值对地图进行排序。您需要为此创建一个变体。由于ZonedDateFormat 实现了 compareTo 方法,因此理想情况下应该可以正常工作。

Comparator dateComparator = new Comparator()   
{  
    public int compare(Object o1, Object o2)   
    {  
        return ((Comparable) ((Map.Entry) 
            (o1)).getValue()).compareTo(((Map.Entry) (o2)).getValue());  
    }  
}

【讨论】:

  • 已更正。谢谢。
【解决方案2】:

你的任务最好不用排序就能解决。您只需要对 entrySet 进行一次迭代。

Map.Entry<Long, ZonedDateFormat> minimum = null;
Map.Entry<Long, ZonedDateFormat> maximum = null;

for (var entry: map.entrySet()) {
  if (minimum == null || minimum.getValue().compareTo(entry.getValue()) > 0) { 
    minimum = entry;
  }
  if (maximum == null || maximum.getValue().compareTo(entry.getValue()) < 0) { 
    maximum = entry;
  } 
}

【讨论】:

    【解决方案3】:

    HashMap 未排序by definition

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

    但可以迭代其条目并对输出进行排序:

    map.entrySet()
        .stream()
        .sorted(Map.Entry.comparingByValue())
        .forEach(System.out::println);
    

    或将排序后的输出转换为LinkedHashMap,保持插入顺序:

    Map<Long. ZonedDateTime> byValue = map.entrySet()
        .stream()
        .sorted(Map.Entry.comparingByValue())
        .collect(Collectors.toMap(
            Map.Entry::getKey,
            Map.Entry::getValue,
            (v1, v2) -> v1,
            LinkedHashMap::new
        ));
    System.out.println(byValue);
    

    【讨论】:

      猜你喜欢
      • 2019-12-06
      • 2021-12-01
      • 1970-01-01
      • 2017-06-13
      • 1970-01-01
      • 2017-08-01
      • 1970-01-01
      • 2015-07-16
      • 2016-10-31
      相关资源
      最近更新 更多