LoginSignup
5
5

More than 5 years have passed since last update.

Streamにおけるmapとflatmapの理解へ向けて(1)

Last updated at Posted at 2019-03-17

問い

2つのIntegerのリストから、
互いの全ての要素の組み合わせから成るPairのリストを生成せよ。

ex.) [1,2,3], [5,6] -> [(1,5),(1,6),(2,5),(2,6),(3,5),(3.6)]

trial1

なんかmapでいけるかも。

List<Integer> ints1 = Arrays.asList(1,2,3);
List<Integer> ints2 = Arrays.asList(5,6);
ints1.stream()
     .map( i -> ints2.stream().map( j -> Pair.of(i,j)))
     .collect(toList()); 

だめ。
List<Stream<Pair<Integer, Integer>>が返される。

そもそも...
Stream.map関数は、型Function<? super T,? extends R>を引数にとり、<R> Stream<R>を返す。

Stream map(Function<? super T,? extends R> mapper)
ref. Stream.map

なので、入れ子となっているmapは、
Stream<Pair<Integer, Integer>>を返し、
その戻り値を受けた大元のmapが、
Stream<Stream<Pair<Integer, Integer>>>を返すようになる。

そして、終端操作により、
List<Stream<Pair<Integer, Integer>>が最終的に返される。
(終端操作がどのような処理をしているかについては今後...)

そこでflatMap

flatMapを使うことで、
Streamの各値を別のStreamで置き換え、
生成された全てのStreamは、単一のStreamへ集約されるようになる。
ref. Java8 in Action

定義によると、
flatMapへ引数で渡している
Function<? super T,? extends Stream<? extends R>> mapperの第二引数が、
? extends Stream<? extends R>となっており、
戻り値は、
Functionの第二引数のStreamを構成する型Rの<R> Stream<R>となっている。

Stream flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
ref. flatMap

以上を踏まえると、以下のようなコードとなる。

ints1.stream()
     .flatMap( i -> ints2.stream().map( j -> Pair.of(i,j)))
     .collect(toList());

flatMap( i -> ints2.stream().map( j -> Pair.of(i,j)))
によって返される型は、
Stream<Pair<Integer,Intege>>で、
終端操作により、List<Pair<Integer,Integer>>が返される。

flatMapを使うことで、
trial1で入れ子となっていたStreamをよしなにしてくれる感じになる ^^;(説明雑)

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5