what does java8 stream map do here?
strings.stream().map(s->map.put(s, s));
does nothing, since the stream pipeline is not processed until you execute a terminal operation. Therefore the Map
remains empty.
Adding a terminal operation to the stream pipeline will cause map.put(s, s)
to be executed for each element of the Stream
required by the terminal operation (some terminal operations require just one element, while others require all elements of the Stream
).
On the other hand, the second stream pipeline:
strings.stream().forEach(s->map.put(s, s));
ends with a terminal operation - forEach
- which is executed for each element of the Stream
.
That said, both snippets are misusing Stream
s. In order to populate a Collection
or a Map
based on the contents of the Stream
, you should use collect()
, which can create a Map
or a Collection
and populate it however you like. forEach
and map
have different purposes.
For example, to create a Map
:
List<String> strings = Lists.newArrayList("1", "2");
Map<String, String> map = strings.stream()
.collect(Collectors.toMap(Function.identity(),
Function.identity()));
System.out.println(map);
The difference is this:
- The idea of
forEach()
is to "work" on each element of the underlying collection (by having a side effect) whereas map()
is about applying a method on each object and putting the result of that into a new stream
That is also the reason why your stream().map()
doesn't result in something - because you throw away the new stream created by the map()
call!
In that sense, the signatures of the two methods tell you that:
void forEach(BiConsumer<? super K,? super V> action)
Performs the given action for each entry in this map until all entries have been processed
versus
<R> Stream<R> map(Function<? super T,? extends R> mapper)
Returns a stream consisting of the results of applying the given function to the elements of this stream.
And for the record: only map()
is a stream method - forEach()
exists for both, streams and Collections/Iterables.