Lambdaの実装を練習

実行時に使用したOpenJDK1.8.0のバージョンです。

  • 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 の遅延評価を参照ください。
まだまだ、よく解っていないので間違った実装をしているかも?