Sorting a Map in Java 8

Category : Java | Sub Category : Java8 Features | By Prasad Bonam Last updated: 2023-11-13 13:48:48 Viewed : 222


Sorting a Map in Java 8 can be done using the stream() method along with the sorted() method. Here is an example of sorting a Map by its keys and values:

java
import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; public class MapSortingExample { public static void main(String[] args) { // Sample map with unsorted data Map<String, Integer> unsortedMap = new HashMap<>(); unsortedMap.put("John", 30); unsortedMap.put("Jane", 25); unsortedMap.put("Bob", 35); unsortedMap.put("Alice", 28); System.out.println("Unsorted Map: " + unsortedMap); // Sorting the map by keys Map<String, Integer> sortedByKey = unsortedMap.entrySet() .stream() .sorted(Map.Entry.comparingByKey()) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, HashMap::new)); System.out.println("Sorted Map by Key: " + sortedByKey); // Sorting the map by values Map<String, Integer> sortedByValue = unsortedMap.entrySet() .stream() .sorted(Map.Entry.comparingByValue()) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, HashMap::new)); System.out.println("Sorted Map by Value: " + sortedByValue); } }

Output:

mathematica
Unsorted Map: {John=30, Jane=25, Bob=35, Alice=28} Sorted Map by Key: {Alice=28, Bob=35, Jane=25, John=30} Sorted Map by Value: {Jane=25, Alice=28, John=30, Bob=35}

In this example:

  • The unsorted map is created with names as keys and ages as values.
  • The map is then sorted by keys and values separately using the stream() method and the sorted() method.
  • The collect(Collectors.toMap(...)) operation is used to collect the sorted entries back into a map.
  • The Map.Entry.comparingByKey() and Map.Entry.comparingByValue() comparators are used for sorting by keys and values, respectively.
  • In Java 8, the Collectors.toMap method is a convenient way to collect elements from a stream into a Map. The signature of the toMap method is as follows:

    java
    toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)

    Lets break down the parameters used in your example:

    • Map.Entry::getKey: This is the keyMapper, which is a function that extracts a key from an element. In this case, its using a method reference to get the key from a Map.Entry object.

    • Map.Entry::getValue: This is the valueMapper, which is a function that extracts a value from an element. Similar to the key mapper, its using a method reference to get the value from a Map.Entry object.

    • (e1, e2) -> e1: This is the mergeFunction, which is used to resolve conflicts when two elements with the same key are encountered. In this case, it uses a lambda expression to choose the first value encountered and discard the second one.

    • HashMap::new: This is the mapSupplier, which is a supplier providing an empty Map into which the results will be inserted. In this case, it creates a new HashMap to store the key-value pairs.

    Putting it all together, this toMap collector is used to collect elements from a stream of Map.Entry objects into a HashMap, where the keys and values are extracted from the entries using getKey and getValue, respectively. If there are any duplicate keys, the first encountered value is kept.

    Here is an example of how you might use this collector:

    java
    import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Example { public static void main(String[] args) { // Assuming you have a List of Map.Entry objects List<Map.Entry<String, Integer>> entryList = List.of( Map.entry("one", 1), Map.entry("two", 2), Map.entry("three", 3), Map.entry("two", 22) // Duplicate key "two" ); // Using Collectors.toMap with the specified parameters Map<String, Integer> result = entryList.stream() .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, HashMap::new )); System.out.println(result); } }

    In this example, the duplicate key "two" will result in the first encountered value being kept in the final map.

    The (e1, e2) -> e1 is a lambda expression representing a BinaryOperator. In the context of the Collectors.toMap method in Java, this lambda expression serves as a merge function to handle situations where two elements in the stream have the same key.

    Here is a breakdown of the parameters of toMap:

    java
    toMap( keyMapper, valueMapper, mergeFunction, mapSupplier )

    In your specific example:

    • keyMapper: Map.Entry::getKey - extracts the key from a map entry.
    • valueMapper: Map.Entry::getValue - extracts the value from a map entry.
    • mergeFunction: (e1, e2) -> e1 - determines what to do when two entries have the same key. In this case, it takes the value of the first entry (e1) and discards the value of the second entry (e2).

    This merge function is necessary because, when collecting elements into a map, there might be situations where two elements have the same key. The mergeFunction is used to specify how to handle such collisions.

    For example, if you have two entries with the same key "A", the mergeFunction will decide which value to keep in the resulting map. In your case, it keeps the value from the first entry (e1). If you wanted to combine the values somehow, you could modify the merge function accordingly.

Search
Related Articles

Leave a Comment: