今日も 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()
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 andconsumeris null
指定された consumer が、もし値が存在しているなら、値を受けとって、さもなければ何もしないようにしてください。
パラメータ: もし値が存在しているなら、ブロックが実行されます。
orElse()
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()
public T orElseGet(Supplier<? extends T> other)
Return the value if present, otherwise invoke other and return the result of that invocation.
パラメータ:
other– aSupplierwhose result is returned if no value is present
戻り値:
the value if present otherwise the result of
other.get()
スロー:
NullPointerException– if value is not present andotheris null
もし存在しているなら、値を返して、さもなければotherを呼び出して、そしてその呼出しの結果を返してください。
パラメータ: 値ではなく、その結果が返されるサプライヤが存在しています
of()
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
Optionalwith the value present
指定された現在の値でオプションを返してください。
パラメータ: 値が存在しています。それは null であってはいけない。
empty()
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 の変更により記述方法が変わるかもしれません。
早く正式リリースされて日本語でこの超便利で素敵な新機能を勉強したい今日この頃です。