-1

I've got a Hashmap like this:

Map<Pair<Date1, Date2>, Pair<DoesntMatter1, DoesntMatter2>> dates = new HashMap<>();

I want to sort that Hashmap at first by Date1 (ascending/chronological) and when Date1 dates are equal, then by Date2. How to do it in a proper and efficient way?

Any help appreciated!

  • 3
    Do you mean you want to end up with a list of the map entries sorted by their keys, with each key sorted first by Date1 then by Date2? – Dave Newton Mar 20 '22 at 20:16
  • 3
    This is not a help forum, and you are expected to demonstrate some research effort before asking questions here. Update your question with a _specific_ problem you have when trying to sort the HashMap. – skomisa Mar 20 '22 at 20:18
  • HashMaps should not be sorted by any value of the key, except the hashing algorithm delivers already such a value, what would be a quite bad hashing algorithm - perhaps start [here](https://en.wikipedia.org/wiki/Hash_function) – BitLauncher Mar 20 '22 at 20:20
  • Write a [Comparator](https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html) for `Pair`. – Chaosfire Mar 20 '22 at 20:20
  • Just don't use a `HashMap`, use a `TreeMap`. – Louis Wasserman Mar 20 '22 at 20:20
  • @DaveNewton It is an option. – voteforkodaline Mar 20 '22 at 20:26

1 Answers1

1

Here are several ways. Given two records (classes would also work).

record Pair<T> (T getItem1, T getItem2) {
}
record OtherObject() {}

The first simply establishes a TreeMap as suggested by Louis Wasserman in the comments. A comparator first compares the first item of the pair, and, if equal, the second item. To resolve object inference issues, the first comparison uses a lambda. The next comparison can then use a method reference.

Comparator<Pair<LocalDate>> comp = Comparator.comparing(
                    (Pair<LocalDate> p) -> p.getItem1())
                    .thenComparing(Pair::getItem2);

Now establish the TreeMap using the comparator.

NavigableMap<Pair<LocalDate>, Pair<OtherObject>> navigableMap = new TreeMap<>(comp);

The second way simply sorts the map entries based on the map key and places them in a list. The first item the comparator is a keyExtractor, the return type of which is Pair<LocalDate> used in the comparisons.

List<Entry<Pair<LocalDate>,Pair<OtherObject>>> entryList = 
      someMap.entrySet().stream().sorted(Comparator.comparing(Entry::getKey,
               Comparator.comparing(
                    (Pair<LocalDate> p) -> p.getItem1())
                    .thenComparing(Pair::getItem2))).toList();

    

Note: TreeMap implements NavigableMap which extends SortedMap which extends Map

WJS
  • 36,363
  • 4
  • 24
  • 39