#まとめ
mapは自身のstreamオブジェクトに格納された全ての要素を変換する
mapメソッドは2つの型変数を利用する
StreamインターフェースはStream<T>
を受け取り、mapメソッドはStream<R>
を返す。
#mapメソッド シグニチャー
public interface Stream<T> ...
<R> Stream<R> map(Function<? super T,? extends R> mapper)
###1行目
Streamインターフェースの宣言をしている。
ここでは、型変数のTを指定して、総称型のインターフェースにしている。
つまり任意の型を扱うことができる。
###2行目
mapメソッドのシグニチャーを定義している。
<R>
-> 型変数の宣言
-> mapメソッドではTとRという2つの型変数を利用できるようにしている。
Stream<R>
-> mapメソッドの戻り値の宣言
-> mapメソッドの戻り値はStream型
mapメソッドはStream<T>インターフェースに定義されているので、このメソッドはStream<T>
をStream<R>
に変換する役割を持つことになる。
map
-> メソッド名
Function<? super T, ? extends R>
-> 引数の型
-> FunctionはJava8から導入された関数型インターフェース
-> Functionインターフェースは、T型のオブジェクトを受け取り、R型のオブジェクトを返す
-> ? super
および? extends
は境界ワイルドカードと呼ぶ記法
-> これで、mapメソッドに渡せる関数の範囲を広くしている。
mapper
-> 仮引数名
#例
public List<String> collectEmpNames(List<Employee> employees) {
return employees.stream()
.map(e -> e.getName())
.collect(Collectors.toList());
}
###1行目
stream()メソッドを呼び出して、EmployeeのListをStreamに変換している。
###2行目
mapメソッドを呼び出している。
EmployeeのStream内の各要素から名前を取り出して、文字列のStreamに変換する。
e -> e.getName()
mapメソッドはFunction型の関数オブジェクトを引数にとる。
上記のラムダ式はFunctionインターフェースを実装したオブジェクトになる。
具体的にいうと...
mapメソッドが呼ばれた時点でStreamに格納されているのはEmployee。
つまり、型TはEmployee。
そのため式の右辺でEmployeeクラスのgetName()を呼び出すことができる。
getName()の戻り値はStringのため、mapメソッドの戻り値はStream<String>になる。
###3行目
collectメソッドを呼び出して、StreamをListに変換している。