簡體   English   中英

如何在 map 中找到最近的 joda DateTime?

[英]How do I find the most recent joda DateTime in map?

我有一個從 Firebase 實時數據庫更新的 map,所以我事先不知道 map 的大小。

在 map 中,我有一個 String 作為鍵,一個 Joda DateTime作為值。

我不知道如何遍歷 map 以返回最新的日期時間。

我會嘗試更好地解釋:

//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,它不允許我使用 Java 8。我必須使用 Java 7 功能。

如何遍歷 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循環的任何 Java 版本:

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);

以上,根據自己需要最新的key、value,還是entry(key+value),按需調整。


最后,只剩下一對具有最近日期的鍵/值

最好的方法是在找到最新條目后替換 map,或者至少替換內容。

Java 8+ 使用 Streams(替換地圖):

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

任何使用for循環的 Java 版本(替換內容):

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());

您可以對 map 值中的DateTime對象使用.isAfter()方法來檢查一個是否在另一個之后。

創建一個String mostRecentKey變量或類似的東西,並將其設置為 map 中的第一個鍵值。然后遍歷myMap.keySet() ,將每個日期 object 值與最近的值與.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 中刪除所有條目,其中值不是我要查找的內容

基本上,你可以這樣做:

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

編輯 - 忘記了你不能修改你正在迭代的集合,稍微改變了方法。

Java 7 解決方案

我在 Android 中使用的最小值是 sdk,它不允許我使用 Java 8。我必須使用 Java 7 功能。

    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);
    }

此片段中的 Output 在我的時區(在 jdk.1.7.0_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 中,因此值不是最新日期的條目將被刪除。 所以這個調用完成了它。

旁注:考慮 ThreeTenABP

如果您還沒有經常使用 Joda-Time,您可以考慮使用 java.time、現代的 Java 日期和時間 API 以及 Joda-Time 的后繼者。 它已經被反向移植並且也可以在低 Android API 級別上工作。

java.time鏈接

您也可以遍歷 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());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM