もっと Lambda その2

今日も Java8 の新機能に慣れるべくネットから情報収集したものを試してみます。

今回の情報源も外国語のサイトなので詳しいことは理解できませんでしたが雰囲気だけでも感じてみたいと思います。(なんのこっちゃ?

ってな訳で今回は「JDK8 Lambda その他いろいろ なんでもいいから動かしてみる」シリーズでもお馴染みの Optional です。

前はストリームでゴニョゴニョしていたので今回は素のままで。

シンプルなコードなのでだいたいのことは解るような気がします。

mylambdaexamples_2\Person.java
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());
    }
}

mylambdaexamples_2\MyLambdaExamples_2.java
package mylambdaexamples_2;

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

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();
        });
        
        // みっけ
        Optional found = find("はるか", person);
        found.ifPresent(f -> {
            System.out.println(f.getLastName());
        });
        
        // いない
        Optional found2 = find("はる", person);
        System.out.println(found2.orElse(new Person("名無しの", "権兵衛", LocalDate.of(2013, 4, 1), Person.Sex.MALE)).getLastName());
        
        // いない
        Optional found3 = find("るか", person);
        System.out.println(found3.orElseGet(() -> {
            return new Person("日本", "太郎", LocalDate.of(2002, 4, 18), Person.Sex.MALE);
        }).getLastName());
    }

    private static Optional find(String lastName, List person) {
        for (Person persons : person) {
            if (persons.getLastName().equals(lastName)) {
                System.out.println("\nみっけ");
                return Optional.of(persons);
            }
        }
        System.out.println("\nいない");
        return Optional.empty();
    }

}


今回また見慣れないメソッドがでてきました。

JavaDoc をちらっと見てみましょう。

 

ifPresent()

java.​util.​Optional

public void ifPresent(Consumer<? super T> consumer)

Have the specified consumer accept the value if a value is present, otherwise do nothing.

パラメータ:

consumer – block to be executed if a value is present

スロー:

NullPointerException – if value is present and consumer is null

指定された consumer が、もし値が存在しているなら、値を受けとって、さもなければ何もしないようにしてください。

パラメータ: もし値が存在しているなら、ブロックが実行されます。

 

orElse()

java.​util.​Optional

public T orElse(T other)

Return the value if present, otherwise return other.

パラメータ:

other – the value to be returned if there is no value present, may be null

戻り値:

the value, if present, otherwise other

値が存在するならばそれを、存在しないなら他を

パラメータ: 他の値が存在しない場合返される値は null かもしれない。

いつものことだけど翻訳支援ソフトって微妙・・・

 

orElseGet()

java.​util.​Optional

public T orElseGet(Supplier<? extends T> other)

Return the value if present, otherwise invoke other and return the result of that invocation.

パラメータ:

other – a Supplier whose result is returned if no value is present

戻り値:

the value if present otherwise the result of other.get()

スロー:

NullPointerException – if value is not present and other is null

もし存在しているなら、値を返して、さもなければotherを呼び出して、そしてその呼出しの結果を返してください。

パラメータ: 値ではなく、その結果が返されるサプライヤが存在しています

 

of()

java.​util.​Optional

public static <T> Optional<T> of(T value)

Return an Optional with the specified present value.

パラメータ:

value – the value to be present, which must be non-null

戻り値:

an Optional with the value present

指定された現在の値でオプションを返してください。

パラメータ: 値が存在しています。それは null であってはいけない。

 

empty()

java.​util.​Optional

public static <T> Optional<T> empty()

Returns an empty Optional instance. No value is present for this Optional.

型パラメータ:

T – Type of the non-existent value

戻り値:

an empty Optional

空の Optional インスタンスを返します。 値なしはこの Optional のために存在しています。

型パラメータ: 実在しない値のタイプ

 

英語じゃなくて日本語の JavaDoc がいいなぁ・・・

以上のことを踏まえてコードを見てみると、名前で検索かけてヒットしたら”みっけ”と名前を表示。

38 行目の検索ではヒットしないので ”いない” と orElse(T other) によって権兵衛が表示されます。

orElse(T other) はデフォルト値を返すために使われるようです。

42 行目の検索でもヒットしないので ”いない” と orElseGet(Supplier<? extends T> other) によって太郎が表示される。

orElseGet(Supplier<? extends T> other) は、もし optional のオブジェクトが空であるなら、究極的にデフォルトの答えを提供することができるサプライヤを提供するために使います。

ちょっと面倒な例外処理のようですね。

さて、このプログラムの実行結果を一応載せておきますね。

 

<– 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

みっけ
はるか

いない
権兵衛

いない
太郎

今回も未来の素敵なコードの欠片を試すことができました。

英語が良く解らないので仕組みがいまいち理解できないのがちょっと残念だけどゆっくりぼちぼちと楽しんで覚えていこう!(^_^)

それではお約束です。

この「もっと Lambda 」は、インターネット上で得た情報を元にそれを少し変更しているだけです。

悲しいことにその情報源は英語なので詳しい内容はわかりません。

よって私の推測で解釈された内容となってますので間違いがあると思います。

Java8 もまだ build85 を使用していますので API の変更により記述方法が変わるかもしれません。

早く正式リリースされて日本語でこの超便利で素敵な新機能を勉強したい今日この頃です。

 

Hatena タグ:

もっと Lambda

Java8 の注目の新機能の Lambda についてなんでもいいから情報を拾い集めて動かしてみることをしています。

今回は Predicate インターフェイスと Consumer インターフェイスです。

この情報源も英語なので詳しく読むことができませんでした。

コードよりだいたいのことを理解できればと思い、参考にさせてもらってほぼ丸写しのサンプルを作りました。(^_^;

非常にシンプルなので特に説明の必要はないと思いますが JavaDoc の内容を一部コメントとして記載しておきました。

jp\yucchi\preidcate_consumer\Person.java
package jp.yucchi.preidcate_consumer;

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

public class Person {
    public enum Sex {

        MALE, FEMALE
    }

    String SAN_OR_CHAN = "たん";

    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 + SAN_OR_CHAN ;
    }

    public Sex getGender() {
        return gender;
    }

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

    void printPerson() {
        System.out.println(firstName + " " + lastName +  SAN_OR_CHAN + ", " + this.getAge() + "歳" + ", Gender: "
                + this.getGender());
    }
}
jp\yucchi\preidcate_consumer\Preidcate_Consumer.java
package jp.yucchi.preidcate_consumer;

import java.time.LocalDate;
import java.util.function.Consumer;
import java.util.function.Predicate;

public class Preidcate_Consumer {

    public static void main(String[] args) {

        Person kyouko = new Person("深田", "恭子", LocalDate.of(1982, 11, 2), Person.Sex.FEMALE);
        Person saki = new Person("武井", "咲", LocalDate.of(1993, 12, 25), Person.Sex.FEMALE);

        System.out.println("\n<-- Person 表示 -->");
        kyouko.printPerson();
        saki.printPerson();

        System.out.println("\n<-- アップデート後のPerson 表示 -->");
        kyouko = updateInfo(kyouko,
                // Lambda expression for Predicate interface
                person -> person.getAge() > 20,
                // Lambda expression for Consumer inerface
                person -> person.SAN_OR_CHAN = "さん");

        kyouko.printPerson();

        saki = updateInfo(saki,
                // Lambda expression for Predicate interface
                person -> person.getAge() < 20,
                // Lambda expression for Consumer inerface
                person -> person.SAN_OR_CHAN = "ちゃん");
        saki.printPerson();
    }

    public static Person updateInfo(Person person,
            Predicate predicate,
            Consumer consumer) {

        // java.util.function.Predicate
        if (predicate.test(person)) { // Returns true if the input object matches some criteria.
            // java.util.function.Consumer
            consumer.accept(person); // Accept an input value.

        }
        return person;
    }
}

まず、Person インスタンスを二つ作ってその内容を表示させます。

次に Predicate インターフェイスの test() メソッドで年齢条件の判定をし、

Consumer インターフェイスの accept() メソッドで Person インスタンスのデータを操作しています。

それぞれアップデートされた内容で表示させてます。

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

 

<– Person 表示 –>
深田 恭子たん, 30歳, Gender: FEMALE
武井 咲たん, 19歳, Gender: FEMALE

<– アップデート後のPerson 表示 –>
深田 恭子さん, 30歳, Gender: FEMALE
武井 咲ちゃん, 19歳, Gender: FEMALE

”たん”から”さん”もしくは”ちゃん”に変更されてますね。(^_^)

たとえば Preidcate_Consumer.java の 29 行目が 16 歳より若い条件だったら次のようになります。

 

<– Person 表示 –>
深田 恭子たん, 30歳, Gender: FEMALE
武井 咲たん, 19歳, Gender: FEMALE

<– アップデート後のPerson 表示 –>
深田 恭子さん, 30歳, Gender: FEMALE
武井 咲たん, 19歳, Gender: FEMALE

Predicate インターフェイスの test() メソッドで年齢条件の判定結果が false になるので

Consumer インターフェイスの accept() メソッドが実行されないので元のまま表示されます。

それではお約です。

この「もっと Lambda 」は、インターネット上で得た情報を元にそれを少し変更しているだけです。

悲しいことにその情報源は英語なので詳しい内容はわかりません。

よって私の推測で解釈された内容となってますので間違いがあると思います。

Java8 もまだ build85 を使用していますので API の変更により記述方法が変わるかもしれません。

早く正式リリースされて日本語でこの超便利で素敵な新機能を勉強したい今日この頃です。

Hatena タグ: