Java8のStream API mapメソッドを理解するにはFunctionインタフェースを理解する
Functionインタフェースを理解すればmapの動きが理解しやすいと思います。
java.util.function.Functionインタフェースは関数型インタフェースと呼ばれるインタフェースで、applyメソッド一つだけを持っています。
public interface Function<T, R> { R apply(T t); // T型の仮引数をR型に変換してreturnする }
TとRを持ち、applyメソッドは仮引数にT,戻り値がRとなります。
Employeeクラスがあるとします。
public class Employee { private String name; private int age; public Employee(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
mapの引数はFunctionなので、匿名クラスを作成してみます。applyメソッドが返すのはここでは固定の文字列としています。TがEmployee型、RがString型です。
List<Employee> list = new ArrayList<Employee>(); list.add(new Employee("tanaka", 44)); list.add(new Employee("takahashi", 40)); list.add(new Employee("minami", 30)); list.add(new Employee("higashiguchi", 32)); list.add(new Employee("adachi", 200)); list.add(new Employee("rasubosu", 25)); List<String> str = list.stream().map(new Function<Employee, String>() { public String apply(Employee e) { // Employeeを仮引数に持ち、String型を返す return "xx"; // ここでは固定値としている } }).collect(Collectors.toList()); // 注
上記からapplyメソッドは仮引数を変換処理したりして、別の型で返すことができることがわかります。
list変数はEmployeeインスタンスのリストですが、mapメソッドを使用することによって、Stream<String>(ここではList<String>にしている)に変換できていることがわかります。こういった変換処理をする場合にmapメソッドを使用します。
List<String> ret = list.stream().map(e -> e.toUpperCase()).collect(Collectors.toList()); // 注 ret.forEach(e -> System.out.println(e));
ちなみに関数型インタフェースは匿名クラスである必要はありません。以下のように定義することも可能です。
Function<Employee, String > func = new Function<Employee, String>() { public String apply(Employee e) { return "xx"; } };
ラムダ式で書く
ラムダ式で書くと以下のように記述できます。
Function<Employee, String > func = e -> e.getName().toUpperCase(); // ラムダ式 List<String> ret = list.stream().map(func).collect(Collectors.toList()); // mapメソッドの引数にfunc 注
このラムダ式は、Functionインタフェースがapplyメソッド一つしか持たない為、applyメソッドを呼んでいるのと同じ意味になります。メソッド名もreturnも{}も省略しているだけです。
// ラムダ式の実際のイメージ public String apply(Employee e) { return e.getName().toUpperCase(); }
ここではapplyメソッドの仮引数はEmployeeで、戻り値がStringになっているので、eがEmployeeの仮引数、e.getName().toUpperCase()はString型です。
Java8のStream API filterメソッドを理解するにはPredicateインタフェースを理解する
注:Java16から以下メソッド追加されました。
.collect(Collectors.toList());
↓
.toList();
KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES6),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^
コメント