もっと Lambda その9

ずっとブログの更新さぼってました。

いろいろネタはあるのですが忙しい毎日を理由の一つとしておきましょう。( ̄。 ̄;)

それと体の調子が良くなくて病に倒れてました。

なんとか復活したので Java8 のエントリーをサクッとポストしようかとがんばってみます。

Java Day Tokyo 2013 が開催されてから日本語での Java8 の情報がちらほら見受けられるようになって嬉しいですね。

ということで、「もっと Lambda」シリーズです。

今回は今まで使ったことが無い flatMap を使ってみます。

実はこの flatMap の使いどころが良く解らずにいたのですが「創る Java」の著者である きしださんのブログにて説明があり、

いくつかのリストを組み合わせて一つのリストを創りたい場合に使えるとのことでした。

JavaDoc を参考までに

flatMap()

java.​util.​stream.​Stream

public Stream flatMap(Function> mapper)

Returns a stream consisting of the results of replacing each element of this stream with the contents of the stream produced by applying the provided mapping function to each element. If the result of the mapping function is null, this is treated as if the result is an empty stream.

This is an intermediate operation.

パラメータ:
mapper – a non-interfering, stateless function to apply to each element which produces a stream of new values

型パラメータ:
R – The element type of the new stream

戻り値:
the new stream

 

早速試してみました。

package mylambdaexamples_2;

import java.time.LocalDate;
import java.time.Period;

public class Person {

    public enum Sex {

        MALE, FEMALE
    }
    String firstName;
    String lastName;
    LocalDate birthday;
    Sex gender;

    public Person(String firstName, String lastName, LocalDate birthday, Sex gender) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.birthday = birthday;
        this.gender = gender;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public Sex getGender() {
        return gender;
    }

    public int getAge() {
        return Period.between(birthday, LocalDate.now()).getYears();
    }

    void printPerson() {
        System.out.println(firstName + " " + lastName + ", " + this.getAge() + "歳" + ", Gender: "
                + this.getGender());
    }
}
package mylambdaexamples_2;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;

public class MyLambdaExamples_2 {

    public static void main(String[] args) {
        List person = new ArrayList<>();
        person.add(new Person("柴田", "恭平", LocalDate.of(1951, 8, 18), Person.Sex.MALE));
        person.add(new Person("壇", "蜜", LocalDate.of(1980, 12, 3), Person.Sex.FEMALE));
        person.add(new Person("北川", "景子", LocalDate.of(1986, 8, 22), Person.Sex.FEMALE));
        person.add(new Person("綾瀬", "はるか", LocalDate.of(1985, 3, 24), Person.Sex.FEMALE));
        person.add(new Person("佐々木", "希", LocalDate.of(1988, 2, 8), Person.Sex.FEMALE));
        person.add(new Person("剛力", "彩芽", LocalDate.of(1992, 8, 27), Person.Sex.FEMALE));
        person.add(new Person("小栗", "旬", LocalDate.of(1982, 12, 26), Person.Sex.MALE));
        person.add(new Person("堀北", "真希", LocalDate.of(1988, 10, 6), Person.Sex.FEMALE));
        person.add(new Person("武井", "咲", LocalDate.of(1993, 12, 25), Person.Sex.FEMALE));
        person.add(new Person("市原", "隼人", LocalDate.of(1987, 2, 6), Person.Sex.MALE));
        person.add(new Person("深田", "恭子", LocalDate.of(1982, 11, 2), Person.Sex.FEMALE));

        // Person 表示
        System.out.println("\n<-- Person 表示 -->");
        person.forEach(e -> {
            e.printPerson();
        });

        // 女性の名前に”さん”をつけて表示
        person.stream()
                .filter(e -> e.getGender() == Person.Sex.FEMALE)
                .map(Person::getLastName)
                .flatMap(e -> Arrays.asList(e.concat("さん")).stream())
                .forEach(System.out::println);

    }
}

女性の名前に”さん”をつけるだけのプログラムです。

filter(e -> e.getGender() == Person.Sex.FEMALE) で女性だけ対象として

map(Person::getLastName) で名前でストリームオブジェクトを再構築し、

flatMap(e -> Arrays.asList(e.concat(“さん”)).stream()) で”さん”を付け足して新たにストリームオブジェクトを再構築してできあがり。(^_^)

”さん”を付けるだけのプログラムならこんなことはしなくてもいいけど名前に”さん”を付けたストリームオブジェクトを新たに必要とするときに便利かもしれませんね。

実行結果は期待通りです。

<– Person 表示 –>
柴田 恭平, 61歳, Gender: MALE
壇 蜜, 32歳, Gender: FEMALE
北川 景子, 26歳, Gender: FEMALE
綾瀬 はるか, 28歳, Gender: FEMALE
佐々木 希, 25歳, Gender: FEMALE
剛力 彩芽, 20歳, Gender: FEMALE
小栗 旬, 30歳, Gender: MALE
堀北 真希, 24歳, Gender: FEMALE
武井 咲, 19歳, Gender: FEMALE
市原 隼人, 26歳, Gender: MALE
深田 恭子, 30歳, Gender: FEMALE
蜜さん
景子さん
はるかさん
希さん
彩芽さん
真希さん
咲さん
恭子さん

Java8 のリリースが来年の2月に変更になったようです。

たしか Future Complete が2.3日前の予定だったような・・・

いずれにせよ、早くリリースしてほしいです。

Hatena タグ:

もっと Lambda その8

今日は久しぶりに? Java8 の目玉機能の Lambda のエントリーです。

くどいようですがまだまだ引っ張ります。

来年の3月18日なんてあっと言う間にやってきます。

今回はちょっと便利な機能を紹介します。

「もっと Lambda その5」で紹介した機能が API の仕様変更になったようで使えなくなりました。

今回は仕様変更されたコードを紹介します。そのおまけとしてステップ数も追加してみました。

1 から 10 までをステップ数 2 で表示する超シンプルなプログラムです。

package jp.yucchi.pkg1_to_10;

import java.util.stream.IntStream;

public class One2Ten {

    public static void main(String[] args) {
         IntStream.range(1, 11, 2).forEach(System.out::print);
    }

}

実行結果は次のようになります。

13579

期待通りの結果ですね。(^^)

何気に便利に使えるかも!

Hatena タグ: