Tuesday, May 12, 2020

How to convert a Map to List in Java 8

Oracle Java Tutorial and Material, Oracle Java Certification, Oracle Java Exam Prep, Oracle Java 8

When you convert a Map to List in Java 8 or before, you have three choices, like you can get a list of keys from Map, List of values from Map, or a List of entries from Map, which encapsulates both key and value. The API doesn't provide these methods because Map doesn't guarantee any order and List interface guarantee ordering, i.e. insertion order. Hence, JDK API provides an equivalent method to convert a Map to Set, like keySet() will return a set of keys and entrySet() will return a set of entries. Since Set cannot have duplicates and Map also cannot have duplicate keys, the Set data structure seems to perfect for returning keys and entries.

But, values can be duplicated in Map; hence API provides values() method which returns Collection. Before Java 8, the problem of converting a Map to List is actually a problem of converting Map to Set and then to List, which is also not different in Java 8. Still, because of Streams and lambda expression, it seems you are doing everything in one step.

1. Map to List of keys


Here is a one-liner to convert a Map of Integer and String, where Integer is key, and String is the type of value, to a List of Integer, i.e. list of keys:

idToName.keySet().stream().collect(Collectors.toList());

In this code, we first get the set of keys by calling the keySet() method and them a stream of keys by calling stream() method. After that, you just need to convert the Stream to List, which we have done using Collectors.toList() method, as shown in the earlier example.

Just keep in mind that toList() can return any kind of List implementation, like ArrayList or LinkedList or even Vector, it's up to the implementation. If you want a particular implementation, like ArrayList, you can use another method called toCollection(), which accepts a Supplier to denote the implementation class.

For example, you can convert a Map to ArrayList of keys by using the following snippet:

idToName.keySet()
        .stream()
        .collect(Collectors.toCollection(ArrayList::new));

or, you can use the below code to convert a Map to LinkedList in Java.

idToName.keySet()
        .stream()
        .collect(Collectors.toCollection(LinkedList::new))

Oracle Java Tutorial and Material, Oracle Java Certification, Oracle Java Exam Prep, Oracle Java 8

2. Map to List to Values


Here is the one line of code to create a list of values from Map:

idToName.values()
        .stream()
        .collect(Collectors.toCollection(ArrayList::new))

The only difference is that this list may contain duplicates because values can be repeated in a Map.

3. Map to List of entries


Here is the one line of code to create a list of values from Map:

idToName.entrySet()
        .stream()
        .collect(Collectors.toCollection(ArrayList::new))

This list will contain all the entries from the Map.

4. Map of Entries to List of Objects


Now, you have a situation where you need to create an object by using key and value from Map, e.g. a Pair object which contains both key and values. Though you can easily use Map.Entry if you want both key and value as shown in the previous example, the new object teach you an essential technique of mapping Stream elements to other object using map() method.

idToName.entrySet()
        .stream()
                    .map( e -> Pair::new)
        .collect(Collectors.toCollection(ArrayList::new))

Important points


1) The keySet() method returns a Set of keys; you need this method because stream() is not available in java.util.Map class.

2) The entrySet() method return a Set of Map.Entry object which contains both key and value.

3) The values() method returns a Collection of values because the value can be duplicate as opposed to Set. See the difference between keySet, values, and entrySet to learn more.

4) The toList() method of Collector returns a List without any guarantees on the type, thread-safety, mutability, and serializability. It can return elements of String in an ArrayList or LinkedList or any custom implementation.

5) If you want to accumulate Stream elements into ArrayList, then you must use toCollection() method and pass ArrayList::new. This will then return an ArrayList of keys. You can use this technique to convert Map to any type of List in Java.

That's all about how to convert a Map to a List in Java 8. You have learned how to convert a Map to the ArrayList and LinkedList. You have also learned how to create a List of Keys and List of values, along with a list of entries from Map object. If you want to learn more about essential Java 8 concepts, you can check the following resources.

Related Posts

0 comments:

Post a Comment