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

Time:04-04

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?

CodePudding user response:

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);

CodePudding user response:

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()));
  • Related