user7704710
user7704710

Reputation: 43

Does flatMap method only flattens the stream and not map it?

I see it's written everywhere that flatMap flattens and map the stream but in practical for example in the below program using only flatMap we can't perform mapping operation(changing it to uppercase). We need to separately use map method here.

List<String> uppercase = Stream.of(asList("A", "B"), asList("C", "D"))
            .flatMap(List::stream)
            .map(String::toUpperCase)
            .collect(Collectors.toList());
    System.out.println(uppercase);

Is my understanding about flatMap wrong? Can anyone please help to understand this - whether flatMap only flattens the stream or it can flattens & map both? If so then how can we write code for that?

Upvotes: 4

Views: 870

Answers (2)

Prasath
Prasath

Reputation: 1284

For better understanding, see the return type difference in both case.

Stream<Stream<String>> i = listOfList.stream().map(li->li.stream());
Stream<String> j = listOfList.stream().flatMap(li->li.stream());

Stream<String> stream1 = Stream.of("A", "B");
Stream<String> stream2 = Stream.of("C", "D");
    
Stream<Stream<String>> result1 = Stream.of(stream1,stream2).map(str->str.map(s->s.toUpperCase()));
Stream<String> result2 = Stream.of(stream1,stream2).flatMap(str->str.map(s->s.toUpperCase()));

Upvotes: 1

ernest_k
ernest_k

Reputation: 45309

It's only those specific method references that limit you. Using a lambda expression, you can still do both:

.flatMap(list -> list.stream().map(String::toUpperCase))
.collect(Collectors.toList());

I should mention that it's only that sequence of method references that limited you, not that it's impossible to do it with method references. The key is the mapper you pass to it. Take these as examples:

Stream<String> uppercaseArray(String[] a) {
    return Arrays.stream(a).map(String::toUpperCase);
}
Stream.of(new String[] {"ab"}, new String[] {"cd", "ef"})
    .flatMap(this::uppercaseArray); //map and transform

// Or a completely different perspective
Stream.of("abc", "def").flatMapToInt(String::chars);

Upvotes: 4

Related Questions