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>>
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);
}
}
java.lang.IllegalStateException: Duplicate key Harley Davidson
I would like to have a way where
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.{CAR=[Audi], BIKE=[Harley Davidson, Pulsar]}
Duplicate keys are not allowed in 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.
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.
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.
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;}));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With