Lambdaの実装を練習
- 1. filterして対象のPersonのnameをforEachで出力、これは正常にコンパイル実行できました。
List<Person> persons = new ArrayList<>(); persons.add(new Person("name10", 10)); persons.add(new Person("name20", 20)); persons.add(new Person("name30", 30)); persons.add(new Person("name40", 40)); persons.add(new Person("name50", 50)); System.out.println("-- 1 filter ---------------------------"); persons.stream().filter(p->p.getAge() >= 30).forEach(p -> System.out.println("★1 30以上:" + p.getName()));
PersonクラスのgetAgeメソッドで「getAge:xx」と出力するようにしたのですが、「getAge:xx」が50まで連続出力後「★1getName」が3行出力されるのではないことが。
遅延処理しているのがこれで少し解りました。
-- 1 filter --------------------------- getAge:10 getAge:20 getAge:30 ★1 30以上:name30 getAge:40 ★1 30以上:name40 getAge:50 ★1 30以上:name50
- コンパイルエラーが2のfindFirst、3のsum、5のinto の箇所で?
System.out.println("-- 2 findFirst ---------------------------"); Optional<Person> xxx = persons.stream().filter(p->p.getAge() == 20).findFirst(); System.out.println("★2 firstPerson:" + xxx); System.out.println("-- 3 map & sum ---------------------------"); int total = persons.stream().map(p->p.getAge()).sum(); System.out.println("total:" + total); System.out.println("-- 4 map & forEach ---------------------------"); persons.stream().filter(p->p.getAge() < 20).map(p->p.getAge()).forEach(p->System.out.println("★4 map forEach:" + p)); System.out.println("-- 5 map & into ---------------------------"); List<Person> list = persons.stream().filter(p->p.getAge() <= 20).into(new ArrayList<>());
コンパイル結果は
- コンパイルエラーにならないようにちょっと実装を変更
2の戻り値をObjectに、実行結果は「Optional」?
3の戻り値をObjectに、実行結果は「ValuePipeline」?
5はintoの引数で明示的に
System.out.println("-- 2 findFirst ---------------------------"); Object xxx = persons.stream().filter(p->p.getAge() == 20).findFirst(); System.out.println("★2 firstPerson:" + xxx); System.out.println("-- 3 map & sum ---------------------------"); Object m = persons.stream().map(p->p.getAge()); System.out.println("☆3 map:" + m); System.out.println("-- 4 map & forEach ---------------------------"); persons.stream().filter(p->p.getAge() < 20).map(p->p.getAge()).forEach(p->System.out.println("★4 map forEach:" + p)); System.out.println("-- 5 map & into ---------------------------"); List<Person> list = persons.stream().filter(p->p.getAge() <= 20).into(new ArrayList<Person>()); list.forEach(p-> System.out.println("★5 map Into:" + p.getName()));
実行結果
この結果から「getAge」が2回呼ばれているのは、map&sumのパターンであることが、確かにfilter時とmap時で2回になっていることに納得です。
あと、findFirstでは最初の結果を取得した後は「getAge」が呼ばれていないのが解りました。
-- 2 findFirst --------------------------- getAge:10 getAge:20 ★2 firstPerson:Optional[test.Person@60c9c2d7] -- 3 map & sum --------------------------- ☆3 map:java.util.streams.ValuePipeline@53a816e5 -- 4 map & forEach --------------------------- getAge:10 getAge:10 ★4 map forEach:10 getAge:20 getAge:30 getAge:40 getAge:50 -- 5 map & into --------------------------- getAge:10 getAge:20 getAge:30 getAge:40 getAge:50 ★5 map Into:name10 ★5 map Into:name20
とりあえず実装を、gistにアップしました。Lambdaの実装を練習 · GitHub
エラーになったのはこれです。Lambda practice(do not know what is the problem) · GitHub
遅延処理の詳細は、id:skrbさんの記事Java in the Box Annex: Java Advent Calendar 1 日目 - Project Lambda の遅延評価を参照ください。
まだまだ、よく解っていないので間違った実装をしているかも?