如何在Map中找到最近的joda datetime?

kxxlusnw  于 2021-07-12  发布在  Java
关注(0)|答案(4)|浏览(394)

我有一张Map是从firebase实时数据库更新的,所以我事先不知道Map的大小。
在Map上我有一个字符串作为键,还有一个joda DateTime 作为价值。
我不知道如何遍历Map以返回最近的datetime。
我会尽量解释得更好:

//on returning results from Realtime Database
  Map<String, DateTime> myMap = new HashMap<>();

    if(dataSnapshot.exists){

       for(DataSnapshot data:dataSnapshot.getChildren()){

           String key = data.getKey();
           DateTime dateTime = // I get the data and convert it to Datetime; no problem here; I can do it.

           myMap.put(key, dateTime);

       }

   //outside the Loop
   //HERE IS WHAT I NEED HELP WITH

      for(DateTime date:myMap.values()){

         // 1 - check if date is after the next date in map
         // 2 - if it is, then keep it
         // 3 - if it is not, then remove
         // 4 - in the end, only one pair of key/value with the most recent date is left

      }

    }

你们能帮帮我吗?非常感谢
编辑:对不起,还有一件事。我在android中使用一个最小的sdk,它不允许我使用java8。我必须使用Java7特性。

fquxozlt

fquxozlt1#

如何遍历Map以返回最近的日期时间
java 8+使用流:

// To get latest key (or entry)
String latestKey = myMap.entrySet().stream()
        .max(Entry::comparingByValue)
        .map(Entry::getKey) // skip this to get latest entry
        .orElse(null);
// To get latest value
DateTime latestValue = myMap.values().stream()
        .max(Comparator.naturalOrder())
        .orElse(null);

任何使用 for 回路:

Entry<String, DateTime> latestEntry = null;
for (Entry<String, DateTime> entry : myMap.entrySet()) {
    if (latestEntry == null || entry.getValue().isAfter(latestEntry.getValue()))
        latestEntry = entry;
}
String latestKey = (latestEntry != null ? latestEntry.getKey() : null);

在上面的示例中,根据需要进行调整,具体取决于您是需要最新的键、值还是条目(键+值)。
最后,只剩下一对具有最近日期的键/值
最好的方法是在找到最新条目后替换Map,或者至少替换内容。
java 8+使用流(替换Map):

myMap = myMap.entrySet().stream()
        .max(Comparator.comparing(Entry::getValue))
        .stream().collect(Collectors.toMap(Entry::getKey, Entry::getValue));

任何使用 for 循环(替换内容):

Entry<String, DateTime> latestEntry = null;
for (Entry<String, DateTime> entry : myMap.entrySet()) {
    if (latestEntry == null || entry.getValue().isAfter(latestEntry.getValue()))
        latestEntry = entry;
}
myMap.clear();
if (latestEntry != null)
    myMap.put(latestEntry.getKey(), latestEntry.getValue());
cyej8jka

cyej8jka2#

你可以用 .isAfter() 上的方法 DateTime Map中的对象值,以检查一个是否在另一个之后。
创建 String mostRecentKey 变量或类似的东西,并将其设置为Map中的第一个键值。然后遍历 myMap.keySet() ,将每个日期对象值与 .isAfter() . 最后,你会有最近的约会。
例如

String mostRecentKey;
for (String dateKey : myMap.keySet()){
    if (mostRecentKey == null) {
        mostRecentKey = dateKey;
    }
    // 1 - check if date is after the next date in map
    if (myMap.get(dateKey).isAfter(myMap.get(mostRecentKey))) {
        mostRecentKey = dateKey;
    }
}

然后您就有了最新一个的密钥,您可以选择删除除该项之外的所有条目,保存值或任何您想要的内容。
要删除除找到的条目以外的所有条目,请参考以下问题:从hashmap中删除所有条目,其中value不是我要查找的值
基本上,你可以这样做:

myMap.entrySet().removeIf(entry -> !entry.getKey().equals(mostRecentKey));

编辑-忘记您不能修改正在迭代的集合,方法略有更改。

soat7uwm

soat7uwm3#

java 7解决方案

我在android中使用一个最小的sdk,它不允许我使用java8。我必须使用Java7特性。

Map<String, DateTime> myMap = new HashMap<>();
    myMap.put("a", new DateTime("2020-01-31T23:34:56Z"));
    myMap.put("b", new DateTime("2020-03-01T01:23:45Z"));
    myMap.put("m", new DateTime("2020-03-01T01:23:45Z"));
    myMap.put("c", new DateTime("2020-02-14T07:14:21Z"));

    if (myMap.isEmpty()) {
        System.out.println("No data");
    } else {
        Collection<DateTime> dateTimes = myMap.values();
        DateTime latest = Collections.max(dateTimes);

        System.out.println("Latest date-time is " + latest);
    }

此代码段的输出位于我的时区(在jdk.1.7.0\U 67上测试):
最晚日期时间为2020-03-01t02:23:45.000+01:00
我们需要先检查Map是否是空的,因为 Collections.max() 会抛出异常。
如果您需要从Map中删除所有条目,但保留最新日期的条目除外:

dateTimes.retainAll(Collections.singleton(latest));
        System.out.println(myMap);

{b=2020-03-01t02:23:45.000+01:00,m=2020-03-01t02:23:45.000+01:00}
是不是有点棘手?这个 retainAll 方法从集合中删除不在作为参数传递的集合中的所有元素。我们只传递一组元素,即最新日期时间,因此所有其他元素都被删除。从我们的收藏中删除元素 myMap.values() 反映在我们获取集合的Map中,因此值不是最新日期的条目将被删除。所以这个电话就完成了。

旁注:考虑3TENABP

如果您还没有经常使用joda time,那么可以考虑改用java.time,它是现代的java日期和时间api,也是joda time的继承者。它已经被后端口,并在低android api级别上工作。

java.time链接

java规范请求(jsr)310,其中 java.time 第一次被描述。
三十后港工程 java.time 到Java6和Java7(jsr-310为310)。
threetenabp,android版threeten backport
问:如何在android项目中使用threetenabp,有非常透彻的解释。
oracle教程:date time解释如何使用java.time。

mpgws1up

mpgws1up4#

您也可以遍历entryset,保存最新的条目,然后删除所有内容并将其添加回。

Map<String, DateTime> myMap = new HashMap<>();
    ....

    Entry<String, DateTime> latest = myMap.entrySet().iterator().next();
    for(Entry<String, DateTime> date:myMap.entrySet()){

         // 1 - use isAfter method to check whether date.getValue() is after latest.getValue()
         // 2 - if it is, save it to the latest
      }
    myMap.clear();
    myMap.put(latest.getKey(), latest.getValue());

相关问题