Having a little trouble using the Stream API to get a one to one mapping. Basically, say you've got a class.
public class Item {
private final String uuid;
private Item(String uuid) {
this.uuid = uuid;
}
/**
* @return universally unique identifier
*/
public String getUuid() {
return uuid;
}
}
I'd like a Map<String, Item>
for easy look up. But given a Stream<Item>
there doesn't seem a simple way to arrive at that Map<String, Item>
.
Obviously, Map<String, List<Item>>
ain't no thing:
public static Map<String, List<Item>> streamToOneToMany(Stream<Item> itemStream) {
return itemStream.collect(groupingBy(Item::getUuid));
}
That's the safer more general case, but we do know in this situation that there will only ever be one-to-one. I can't find anything that compiles though -- I've specifically been trying to muck with the downstream
parameter to Collectors.groupingBy
. Something like:
// DOESN'T COMPILE
public static Map<String, Item> streamToOneToOne(Stream<Item> itemStream) {
return itemStream.collect(groupingBy(Item::getUuid, Function.identity()));
}
What am I missing?
Method 1: Using Collectors.toMap() Function The Collectors. toMap() method takes two parameters as the input: KeyMapper: This function is used for extracting keys of the Map from stream value. ValueMapper: This function used for extracting the values of the map for the given key.
Stream map() in Java with examples Stream map(Function mapper) returns a stream consisting of the results of applying the given function to the elements of this stream. Stream map(Function mapper) is an intermediate operation. These operations are always lazy.
concat() in Java. Stream. concat() method creates a concatenated stream in which the elements are all the elements of the first stream followed by all the elements of the second stream. The resulting stream is ordered if both of the input streams are ordered, and parallel if either of the input streams is parallel.
Use the Collectors#toMap(Function, Function)
, generating the key from each Item
's uuid
and the Item
as the value itself.
public static Map<String, Item> streamToOneToOne(Stream<Item> itemStream) {
return itemStream.collect(Collectors.toMap(Item::getUuid, Function.identity()));
}
Note from the javadoc
If the mapped keys contains duplicates (according to
Object.equals(Object)
), anIllegalStateException
is thrown when the collection operation is performed. If the mapped keys may have duplicates, usetoMap(Function, Function, BinaryOperator)
instead.
groupingBy()
collects items (plural, as a List
) by a key.
You want toMap()
:
public static Map<String, Item> streamToOneToOne(Stream<Item> itemStream) {
return itemStream.collect(toMap(Item::getUuid, Function.identity()));
}
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