Sorting a HashMap by date

后端 未结 6 1990
隐瞒了意图╮
隐瞒了意图╮ 2021-02-15 16:00

In a Java class I have a method to reOrder an existing HashMap by date. The HashMap is of a type where the Object contains a field called exp

相关标签:
6条回答
  • 2021-02-15 16:16

    Your best bet will be to use a SortedMap with the Comparator interface.

    Here is an example:

    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;
    }
    
    0 讨论(0)
  • 2021-02-15 16:19

    For simplicity I am assuming that type of your map is something more like Map<String, MyClass> map where MyClass has method like getDate() which returns expPayDate.

    My issue is what is the best way to determine the item with the newest date.

    If you want to find single map entry which value contains max date you don't need to sort entire map which at best would give you O(n*logn). What you need is simple iteration of all elements in map and comparing them with current max, which will be O(n) operation.

    You can use stream() (functionality added in Java 8) and its max method. This method needs Comparator and you can easily create one by using comparing method and passing lambda expression which will return value which should be used when comparing.

    So your code can look like

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

    If you can't use Java 8 you can write your own method which will iterate over elements and find max. Such method can look like

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

    and you can use it like

    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();
    
    0 讨论(0)
  • 2021-02-15 16:19

    The correct solution depends on your performance constraints.

    If your issue is just finding the item with the newest date, then if O(n) performance is OK you can do a scan of the values() in your HashMap and find the minimum that way.

    It depends on how often you need to do this relative to other access on the data structure. It would be perfectly reasonable to use a SortedMap or use a secondary data structure such as a PriorityQueue (acting as a heap on the date), depending on your access patterns for this data structure.

    0 讨论(0)
  • 2021-02-15 16:21
    1. Get all Entries by calling entrySet() method of Map

    2. Create a custom Comparator to sort entries based upon values

    3. Convert Entry set to List

    4. Sort Entry list by using Collections.sort() method by passing your value comparator

    5. Create a LinkedHashMap by adding entries in sorted order.

    Look at example code @ Sort HasMap by value

    0 讨论(0)
  • 2021-02-15 16:32

    If you just need the minimum or maximum date, a simple for each loop might be sufficient:

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

    This way complexity is only O(n) and insert and delete operations are cheaper than using a sortedMap. Anyway, I think patstuart's suggestion (using a sortedMap) is more elegant.

    0 讨论(0)
  • 2021-02-15 16:37

    Use a TreeMap instead of HashMap. it will be sorted automatically on insertion.

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

    Alternatively, if you have an existing HashMap and want to create a TreeMap based on it, pass it to the constructor:

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

    Hope it will help you.

    0 讨论(0)
提交回复
热议问题