Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to collect into a Map forming a List in value when duplicate keys in streams, in Java 8

I have a stream of elements in the form of either 2-D array or EntrySet. I need these to be collected in a Map. Now the issue is the stream of elements can have duplicate elements. Let's say I want the value to be a list:

Map<String,List<String>>

Example :

class MapUtils
{
// Function to get Stream of String[]
private static Stream<String[]> getMapStream()
{
    return Stream.of(new String[][] {
            {"CAR", "Audi"},
            {"BIKE", "Harley Davidson"},
            {"BIKE", "Pulsar"}
    });
}

// Program to convert Stream to Map in Java 8
public static void main(String args[])
{
    // get stream of String[]
    Stream<String[]> stream = getMapStream();

    // construct a new map from the stream
    Map<String, String> vehicle =
            stream.collect(Collectors.toMap(e -> e[0], e -> e[1]));

    System.out.println(vehicle);
}
}

Output :

java.lang.IllegalStateException: Duplicate key Harley Davidson

I would like to have a way where

  1. I can operate on e->e[0] and e->e[1] to have the problem solved. Is that possible? For this I need an access of the current map object that's getting collected. I am not sure if that makes sense.
  2. A way where this can be achieved with Java 8 streams.

Expected Output :

{CAR=[Audi], BIKE=[Harley Davidson, Pulsar]}
like image 657
Nilotpal Avatar asked Sep 03 '18 04:09

Nilotpal


People also ask

Does MAP accept duplicate keys?

Duplicate keys are not allowed in a Map.

How do I find duplicate keys on a map?

Keys are unique once added to the HashMap , but you can know if the next one you are going to add is already present by querying the hash map with containsKey(..) or get(..) method.

How does Stream detect duplicate values in a list?

Get the stream of elements in which the duplicates are to be found. For each element in the stream, count the frequency of each element, using Collections. frequency() method. Then for each element in the collection list, if the frequency of any element is more than one, then this element is a duplicate element.

What happens if we enter duplicate key in map?

If you try to insert the duplicate key, it will replace the element of the corresponding key. HashMap is similar to HashTable, but it is unsynchronized. It allows to store the null keys as well, but there should be only one null key object and there can be any number of null values.


1 Answers

You can use groupingBy

getMapStream()
      .map(item -> Arrays.asList(item))
      .collect(Collectors.groupingBy(l->l.get(0),
           Collectors.mapping(l1->l1.get(1),Collectors.toList())));

or use toMap() with merge function.

     Map<String,List<String>> vehicle = getMapStream()
            .collect(Collectors.toMap(item->item[0],
       item->new ArrayList<>(Arrays.asList(item[1])),
                            (l1,l2)->{l1.addAll(l2);return l1;}));
like image 194
Hadi J Avatar answered Oct 22 '22 10:10

Hadi J