Java 8のflatMapの例

Java 8では、Streamはさまざまなデータ型を保持できます(例:

Stream<String[]>
Stream<Set<String>>
Stream<List<String>>
Stream<List<Object>>

しかし、ストリーム操作(フィルタ、サム、別名…​)とコレクタはサポートしていないため、http://docs.oracle.com/javase/8/docs/api/java/util/stream/が必要です。 Stream.html#flatMap-java.util.function.Function-[flatMap()]を使用して次の変換を行います。

Stream<String[]>      -> flatMap -> Stream<String>
Stream<Set<String>> -> flatMap -> Stream<String>
Stream<List<String>>    -> flatMap -> Stream<String>
Stream<List<Object>>    -> flatMap -> Stream<Object>

`flatMap()`の仕組み:

{ {1,2}, {3,4}, {5,6} } -> flatMap -> {1,2,3,4,5,6}

{ {'a','b'}, {'c','d'}, {'e','f'} } -> flatMap -> {'a','b','c','d','e','f'}

1. Stream String[]flatMap

1.1以下の例は、 `filter()`が `String[]`のストリームをどのようにフィルタリングするかを知らないので、空の結果を出力します。

TestExample1.java

package com.mkyong.java8;

import java.util.Arrays;
import java.util.stream.Stream;

public class TestExample1 {

    public static void main(String[]args) {

        String[][]data = new String[][]{{"a", "b"}, {"c", "d"}, {"e", "f"}};

       //Stream<String[]>
        Stream<String[]> temp = Arrays.stream(data);

       //filter a stream of string[], and return a string[]?
        Stream<String[]> stream = temp.filter(x -> "a".equals(x.toString()));

        stream.forEach(System.out::println);

    }

}

出力

…​.//empty…​

1.2上記の例では、 `FlatMap()`を使って `Stream <String[]>`を `Stream <String>`に変換する必要があります。

TestExample1.java

package com.mkyong.java8;

import java.util.Arrays; import java.util.stream.Stream;

public class TestExample1 {

public static void main(String[]args) {
String[][]data = new String[][]{{"a", "b"}, {"c", "d"}, {"e", "f"}};
//Stream<String[]>
 Stream<String[]> temp = Arrays.stream(data);
//Stream<String>, GOOD!
 Stream<String> stringStream = temp.flatMap(x -> Arrays.stream(x));
Stream<String> stream = stringStream.filter(x -> "a".equals(x.toString()));
stream.forEach(System.out::println);
   /** Stream<String> stream = Arrays.stream(data)
            .flatMap(x -> Arrays.stream(x))
            .filter(x -> "a".equals(x.toString()));** /
}

}

出力

a

===  2.ストリームセットflatMap

2.1生徒POJO。

Student.java

package com.mkyong.java8;

import java.util.HashSet; import java.util.Set;

public class Student {

private String name;
private Set<String> book;
 public void addBook(String book) {
     if (this.book == null) {
         this.book = new HashSet<>();
     }
     this.book.add(book);
 }
//getters and setters

}

2.2 `flatMap()`と `Set`の例です。

TestExample2.java

package com.mkyong.java8;

import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors;

public class TestExample2 {

public static void main(String[]args) {
Student obj1 = new Student();
obj1.setName("mkyong");
obj1.addBook("Java 8 in Action");
obj1.addBook("Spring Boot in Action");
obj1.addBook("Effective Java (2nd Edition)");
Student obj2 = new Student();
obj2.setName("zilap");
obj2.addBook("Learning Python, 5th Edition");
obj2.addBook("Effective Java (2nd Edition)");
List<Student> list = new ArrayList<>();
list.add(obj1);
list.add(obj2);
List<String> collect =
        list.stream()
                .map(x -> x.getBook())     //Stream<Set<String>>
                .flatMap(x -> x.stream())  //Stream<String>
                .distinct()
                .collect(Collectors.toList());
    collect.forEach(x -> System.out.println(x));
}

}

出力

Spring Boot in Action Effective Java (2nd Edition) Java 8 in Action Learning Python, 5th Edition

コメントを `flatMap(x  - > x.stream())`しようとすると、Setオブジェクトのストリームをどのように収集するのか分かりませんので、 `Collectors.toList()`はコンパイラエラーを表示します。

===  3.ストリームプリミティブflatMapToInt

3.1プリミティブ型の場合、 `flatMapToInt`を使うことができます。

TestExample3.java

package com.mkyong.java8;

import java.util.Arrays; import java.util.stream.IntStream; import java.util.stream.Stream;

public class TestExample3 {

public static void main(String[]args) {
int[]intArray = {1, 2, 3, 4, 5, 6};
//1. Stream<int[]>
 Stream<int[]> streamArray = Stream.of(intArray);
//2. Stream<int[]> -> flatMap -> IntStream
 IntStream intStream = streamArray.flatMapToInt(x -> Arrays.stream(x));
intStream.forEach(x -> System.out.println(x));
}

}

出力

1 2 3 4 5 6

=== 参考文献

.  http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#flatMap-java.util.function.Function-[Stream#flatMap

JavaDoc]。 http://stackoverflow.com/questions/26684562/difference-between-map-and-flatmap-methods-in-java-8[Stackoverflow

 -  Java 8におけるmapとflatMapの違い
。リンク://java/java-how-to-print-an-array/[Java 8  - 印刷する方法

アレイ]。リンク://java8/java-8-collectors-groupingby-and-mapping-example/[Java 8

 - コレクタグループ化とマッピングの例]

link://タグ/フラットマップ/[flatMap]リンク://タグ/java8/[java8]リンク://タグ/ストリーム/[ストリーム]