もっと Lambda その10

もっと Lambda シリーズも今回で10回目になりました。

と言っても大した内容ではないので恐縮です。

私のモットーは「門前の小僧習わぬ経を読む」ですから気にせずガンガンいっちゃいます!

今回はストリームオブジェクトの重複要素を排除して新たにストリームオブジェクトを作り直す便利な方法を紹介します。

とても簡単なので覚えておいて損はないと思います。

では、非常にシンプルなプログラムをご覧ください。

package jp.yucchi.trydistinct;

import static java.util.Arrays.stream;

public class TryDistinct {

    public static void main(String[] args) {
        String[] works = {"HONDA", "HONDA", "TOYOTA", "TOYOTA", "TOYOTA", "NISSAN", "MAZUDA"}; 
        stream(works).distinct().forEach(System.out::println);
    }

}

 

distinct() メソッドが重複排除して新たなストリームオブジェクトを返してくれるんですねぇ~(^_^)

たったこれだけです!

distinct()

ava.​util.​stream.​Stream

public Stream<T> distinct()

Returns a stream consisting of the distinct elements (according to Object.equals(Object)) of this stream.

This is a stateful intermediate operation.

戻り値:
the new stream

 

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

HONDA
TOYOTA
NISSAN
MAZUDA

 

便利だね。

調子に乗って二つのリストオブジェクトを結合して重複要素を排除して新たにストリームオブジェクトをつくってみましょう。

package jp.yucchi.tryunion;

import static java.util.Arrays.asList;
import java.util.List;
import java.util.stream.Stream;
import static java.util.stream.Streams.concat;

public class TryUnion {

    public static void main(String[] args) {
        List idol_1 = asList("喜屋武ちあき", "櫻井里佳", "谷澤恵里香", "倉持明日香","戸田恵梨香", "新垣結衣");
        List idol_2 = asList("吉高由里子", "宮崎あおい", "篠田麻里子", "戸田恵梨香", "新垣結衣");
        Stream allIdol = concat(idol_1.stream(), idol_2.stream());
        allIdol.distinct().forEach(System.out::println);
    }

}

 

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

喜屋武ちあき
櫻井里佳
谷澤恵里香
倉持明日香
戸田恵梨香
新垣結衣
吉高由里子
宮崎あおい
篠田麻里子

ちなみに distinct() メソッド無しだと重複要素は排除されません。

Java8 が正式リリースされて何らかの理由によって Java7 を使わなくてはいけない状況があるとすればそれは気の毒としか言いようがないですね。

Hatena タグ:

もっと 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 タグ: