Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling nested Collections with Java 8 streams

Lately I came across a problem during working with nested collections (values of Maps inside a List):

List<Map<String, Object>> items

This list in my case contains 10-20 Maps. At some point I had to replace value Calculation of key description to Rating. So I come up with this solution:

items.forEach(e -> e.replace("description","Calculation","Rating"));

It would be quite fine and efficient solution if all maps in this list will contain key-Value pair ["description", "Calculation"]. Unfortunately, I know that there will be only one such pair in the whole List<Map<String, Object>>.

The question is:

Is there a better (more efficient) solution of finding and replacing this one value, instead of iterating through all List elements using Java-8 streams?

Perfection would be to have it done in one stream without any complex/obfuscating operations on it.

like image 862
Przemysław Gęsieniec Avatar asked Oct 05 '18 09:10

Przemysław Gęsieniec


People also ask

Does Java 8 support streams?

Java 8 offers the possibility to create streams out of three primitive types: int, long and double. As Stream<T> is a generic interface, and there is no way to use primitives as a type parameter with generics, three new special interfaces were created: IntStream, LongStream, DoubleStream.

What are the two types of collections streams offered by Java 8?

With Java 8, Collection interface has two methods to generate a Stream. stream() − Returns a sequential stream considering collection as its source. parallelStream() − Returns a parallel Stream considering collection as its source.

How does Java 8 streams work internally?

Since JDK 8, a spliterator method has been included in every collection, so Java Streams use the Spliterator internally to iterate through the elements of a Stream. Java provides implementations of the Spliterator interface, but you can provide your own implementation of Spliterator if for whatever reason you need it.


1 Answers

items.stream()
     .filter(map -> map.containsKey("description"))
     .findFirst()
     .ifPresent(map -> map.replace("description", "Calculation", "Rating"));

You will have to iterate over the list until a map with the key "description" is found. Pick up the first such, and try to replace.


As pointed out by @Holger, if the key "description" isn't single for all the maps, but rather the pair ("description", "Calculation") is unique:

items.stream()
     .anyMatch(m -> m.replace("description", "Calculation", "Rating"));
like image 199
Andrew Tobilko Avatar answered Sep 23 '22 01:09

Andrew Tobilko