You can achieve it like so with the streams API:
LinkedHashMap<Integer, Integer> resultSet =
map.entrySet().stream()
.sorted(Map.Entry.<Integer, Integer>comparingByValue()
.thenComparing(Map.Entry.comparingByKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(oldValue, newValue) -> oldValue, LinkedHashMap::new));
The sorted intermediate operation can take a Comparator
instance which in this case is:
Map.Entry.<Integer, Integer>comparingByValue()
.thenComparing(Map.Entry.comparingByKey())
i.e. compare by the map values and if two given values are the same then compare by the key.
Moving on to the collect
terminal operation:
Map.Entry::getKey
is the keyMapper
which is a mapping function to produce the map keys.
Map.Entry::getValue
is the valueMapper
which is a mapping function to produce the map values.
(oldValue, newValue) -> oldValue
is the merge function used to resolve collisions between values associated with the same key.
LinkedHashMap::new
provides a new empty Map into which the results will be inserted. We specified a LinkedHashMap
here to maintain insertion order.
Note the merge function (oldValue, newValue) -> oldValue
is pointless in this case as the source of the stream (map.entrySet()
) will never contain duplicate keys. However, we still need it otherwise we cannot specify the type of accumulator for the new values, in this case, a LinkedHashMap
instance to maintain insertion order.
You may also want to look at the toMap method for further information on how it works.