簡體   English   中英

按日期排序HashMap

[英]Sorting a HashMap by date

在Java類中,我有一個按日期重新編譯現有HashMap的方法。 HashMap的類型為<String, Object> ,其中Object包含一個名為expPayDate的字段,鍵字符串是一個序列號變成一個字符串。所以我需要循環遍歷sourceMap中的項目並找到帶有最新的日期然后以正確的順序將其復制到tempMap。 我的問題是確定具有最新日期的項目的最佳方法是什么。

你最好的選擇將是使用的SortedMap比較器接口。

這是一個例子:

public SortedMap<String, Object> getSortedMap(Map<String, Object> originalMap) {
    SortedMap<String, Object> tmpMap = new TreeMap<String, Object>(new Comparator<String>(){
        @Override
        public int compare(String key1, String key2) {
            //logic for comparing dates
        }           
    });
    tmpMap.putAll(originalMap);
    return tmpMap;
}

使用TreeMap而不是HashMap。 它會在插入時自動排序。

Map< Date, Object> m = new TreeMap< Date, Object>();

或者,如果您有一個現有的HashMap並想要基於它創建一個TreeMap,請將其傳遞給構造函數:

Map< Date, Object> sortedMap = new TreeMap< Date, Object>(m);

希望它會對你有所幫助。

  1. 通過調用Map的entrySet()方法獲取所有條目

  2. 創建自定義Comparator以根據值對條目進行排序

  3. Entry設置轉換為List

  4. 通過傳遞值比較器,使用Collections.sort()方法對條目列表進行排序

  5. 通過按排序順序添加條目來創建LinkedHashMap

按值查看示例代碼@ Sort HasMap

為簡單起見,我假設您的地圖類型更像Map<String, MyClass> map ,其中MyClass具有getDate()方法,返回expPayDate

我的問題是確定具有最新日期的項目的最佳方法是什么。

如果你想找到哪個包含最大日期的單個地圖條目, 你不需要對整個地圖進行排序 ,最多只能給你O(n * logn)。 你需要的是對map中所有元素的簡單迭代,並將它們與當前max進行比較,這將是O(n)操作。

您可以使用stream() (Java 8中添加的功能)及其max方法。 這個方法需要Comparator ,你可以通過comparing方法和傳遞lambda表達式輕松創建一個,這將返回比較時應該使用的值。

所以你的代碼看起來像

//import java.util.Map.Entry;

Optional<Entry<String, MyClass>> max = map.entrySet().stream()
        .max(Comparator.comparing(e -> e.getValue().getDate()));

Entry<String, MyClass> entry = max.get();
MyClass maxMC = entry.getValue();

如果你不能使用Java 8,你可以編寫自己的方法,它將迭代元素並找到最大值。 這種方法看起來像

public static <T> T max(Iterable<T> iterable, Comparator<T> comp) {
    Iterator<T> it = iterable.iterator();
    T max = null;
    if (it.hasNext()) {
        max = it.next();
    }
    while (it.hasNext()) {
        T tmp = it.next();
        if (comp.compare(max, tmp) < 0)
            max = tmp;
    }
    return max;
}

你可以像使用它一樣

Comparator<Entry<String, MyClass>> myComparator = new Comparator<Entry<String, MyClass>>() {
    @Override
    public int compare(Entry<String, MyClass> o1, Entry<String, MyClass> o2) {
        return o1.getValue().getDate().compareTo(o2.getValue().getDate());
    }
};
Entry<String, MyClass> maxEntry = max(map.entrySet(), myComparator);
MyClass max = maxEntry.getValue();

如果您只需要最小或最大日期,則每個循環的簡單可能就足夠了:

Date maxDate = null;
for (Entry<String, Object> item: hashMap.entrySet()) 
    if (maxDate == null || maxDate before((Date)item.getValue())) 
        maxDate = (Date)item.getValue();

這種方式復雜性只有O(n),插入和刪除操作比使用sortedMap便宜。 無論如何,我認為patstuart的建議(使用sortedMap )更優雅。

正確的解決方案取決於您的性能限制。

如果您的問題只是找到具有最新日期的項目,那么如果O(n)性能正常,您可以在HashMap中掃描values()並找到最小值。

這取決於您相對於數據結構上的其他訪問需要執行此操作的頻率。 使用SortedMap或使用輔助數據結構(例如PriorityQueue(在日期充當堆))將是完全合理的,具體取決於您對此數據結構的訪問模式。

暫無
暫無

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

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