先日はシステムプロパティを取得するプログラムを組んでみたけど誰からもツッコミが入らなかったのでこのまま
勝手にイケイケでよくあるサンプルコードを JDK 8 ならこんなになるのかって勝手に思い込む遊びをします。
決して良い子のみんなは真似をしないようにね!
とりかえしのつかないことになるといけないからね(爆
今回は Java 8 について Twitter 上で下記のようなつぶやきがあったのでそれも試してみます。
「みんな、Java8のラムダは飾りでメソッド参照こそ本命ということに気づいてきた」
私は新しく使いやすくなる日付関係の Date and Time API が本命だと気付きました。(^_^;)
これも今回ちょこっとだけ使ってみたいと思います。
開発環境はこの前と同じです。
NetBeans 8 Dev の未来を先取りする賢い補完機能にずいぶん助けられます。
Java 8 を気楽に試してみたい人にはお勧めです。
では、今回試してみたプログラムをご覧ください。
素人が組んだものですから生暖かい眼差しで見て間違ってるところやここはこうしたほうがいいよって優しく教えてくれたら感激です。
| jp\yucchi\mylambdasample\MyTeam.java |
package jp.yucchi.mylambdasample;
import java.time.LocalDate;
public class MyTeam {
public enum Sex {
MALE, FEMALE
}
String name;
LocalDate birthday;
Sex gender;
int Breast;
int FightingPower;
public MyTeam(String name, LocalDate birthday, Sex gender, int Breast, int FightingPower) {
this.name = name;
this.birthday = birthday;
this.gender = gender;
this.Breast = Breast;
this.FightingPower = FightingPower;
}
public String getName() {
return name;
}
public int getAge() {
LocalDate today = LocalDate.now();
int age = today.getYear() - birthday.getYear();
if (birthday.getMonthValue() > today.getMonthValue()
|| birthday.getMonthValue() == today.getMonthValue()
&& birthday.getDayOfMonth()
> today.getDayOfMonth()) {
age--;
}
return age;
}
public Sex getGender() {
return gender;
}
public int getBreast() {
return Breast;
}
public int getFightingPower() {
return FightingPower;
}
void printMyTeam() {
System.out.println(name + ", " + this.getAge() + "歳" + ", Gender: "
+ this.getGender() + ", Breast Size: " + this.getBreast()
+ ", FightingPower: " + this.getFightingPower());
}
}
| jp\yucchi\mylambdasample\MyLambdaSample.java |
package jp.yucchi.mylambdasample;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class MyLambdaSample {
public static void main(String... args) {
List member = new ArrayList<>();
member.add(
new MyTeam(
"ほげほげ たこたろう",
LocalDate.of(1980, 6, 20),
MyTeam.Sex.MALE,
90,
100));
member.add(
new MyTeam(
"壇蜜",
LocalDate.of(1980, 12, 3),
MyTeam.Sex.FEMALE,
90,
99));
member.add(
new MyTeam(
"北川 景子",
LocalDate.of(1986, 8, 22),
MyTeam.Sex.FEMALE,
78,
80));
member.add(
new MyTeam(
"綾瀬 はるか",
LocalDate.of(1985, 3, 24),
MyTeam.Sex.FEMALE,
88,
85));
member.add(
new MyTeam(
"佐々木 希",
LocalDate.of(1988, 2, 8),
MyTeam.Sex.FEMALE,
80,
85));
member.add(
new MyTeam(
"剛力 彩芽",
LocalDate.of(1992, 8, 27),
MyTeam.Sex.FEMALE,
77,
75));
member.add(
new MyTeam(
"川口 春奈",
LocalDate.of(1995, 2, 10),
MyTeam.Sex.FEMALE,
75,
70));
member.add(
new MyTeam(
"堀北 真希",
LocalDate.of(1988, 10, 6),
MyTeam.Sex.FEMALE,
78,
76));
member.add(
new MyTeam(
"武井 咲",
LocalDate.of(1993, 12, 25),
MyTeam.Sex.FEMALE,
76,
66));
member.add(
new MyTeam(
"石原 さとみ",
LocalDate.of(1986, 12, 24),
MyTeam.Sex.FEMALE,
82,
89));
member.add(
new MyTeam(
"深田 恭子",
LocalDate.of(1982, 11, 2),
MyTeam.Sex.FEMALE,
90,
84));
// MyTeam 全員表示
System.out.println("<-- MyTeam 全員表示 -->");
member.stream().forEach((e) -> {
e.printMyTeam();
});
// 女性で16歳以上29歳以下さらにバストが76センチ以上
// のチームメンバーを表示する。
System.out.println("MyBestMember");
member.parallelStream().filter( m -> m.getGender() == MyTeam.Sex.FEMALE
&& m.getAge() >= 16
&& m.getAge() <= 29
&& m.getBreast() >= 76)
.collect(Collectors.toList())
.forEach(e -> {
System.out.println(e.getName() +", " + e.getAge() + "歳, "
+ "Gender : " +e.getGender() + ", " + "Breast Size : "
+ e.getBreast() +", FightingPower : " +e.getFightingPower());
});
// MyBestMember の FightingPower を昇順ソート
System.out.println("<-- MyBestMember FightingPower 昇順ソート -->");
member.parallelStream().filter( m -> m.getGender() == MyTeam.Sex.FEMALE
&& m.getAge() >= 16
&& m.getAge() <= 29
&& m.getBreast() >= 76)
.map(MyTeam::getFightingPower)
.sorted(Integer::compareTo)
.collect(Collectors.toList())
.forEach(System.out::println);
// MyBestMember FightingPower 最大値を表示
System.out.println("<-- MyBestMember FightingPower 最大値を表示 -->");
Integer reduce = member.parallelStream().filter( m -> m.getGender() == MyTeam.Sex.FEMALE
&& m.getAge() >= 16
&& m.getAge() <= 29
&& m.getBreast() >= 76)
.map(MyTeam::getFightingPower)
.reduce(0,Math::max);
System.out.println(reduce);
// MyBeatMember を FightingPower 詳細照準ソート
System.out.println("<-- MyBeatMember を FightingPower 詳細照準ソート -->");
member.parallelStream().filter( m -> m.getGender() == MyTeam.Sex.FEMALE
&& m.getAge() >= 16
&& m.getAge() <= 29
&& m.getBreast() >= 76)
.sorted((o1, o2) -> o1.getFightingPower() - o2.getFightingPower())
.collect(Collectors.toList())
.forEach(e -> {
System.out.println(e.getName() +", " + e.getAge() + "歳, "
+ "Gender : " +e.getGender() + ", " + "Breast Size : "
+ e.getBreast() +", FightingPower : " +e.getFightingPower());
});
}
}
プログラムの内容にはあまり触れないでくださいね。
私の好みの問題ですから(〃・ω・〃)
既に気付かれた方もいるでしょうが Date and Time API を使うと非常にシンプルで直感的に使えます。
細かい説明はしませんので JavaDoc をさらってご覧になってくださいませ。
カレンダー関係に悩まされてきたそこの あ・な・た !
やっとイライラから解放されるかもしれません。
カレンダーをセットするのも簡単になってます。(50行目)
今まで月の扱いがうざいなぁって思っていたのがやっと解消されますね。
次に、メソッド参照をみてみましょう。
118行目、120行目、128行目、129行目で使ってます。
:: を使った何かしっくりこない違和感の塊がメソッド参照と呼ばれている新機能です。
引数で渡されたオブジェクトのメソッドを呼ぶ機能のようです。
これは単にコード記述量が少なくなるだけなんだろうか?
他に何かメリットがあるのか良く解りません。
今回は static メソッドを使用してますが特定のオブジェクトのインスタンスメソッドや
特定の型の任意のオブジェクトのインスタンスメソッドが使えるようです。
特定のオブジェクトのメソッド参照は、異なる関数型インターフェースに変換する便利な手段を提供します。
Callable<Path> c = ... PrivilegedAction <Path> a = c::call;
任意のオブジェクトのインスタンスメソッド参照は
Arrays.sort(names, String::compareToIgnoreCase);
と引数の数が違います。任意のオブジェクトのメソッド参照には第一引数にインスタンスを渡してます。
要するにラムダ式を書く代わりに既存のメソッドを呼び出すことができるよってことなのかな?
これが Java 8 の本命なのか?
私が知らないもしくは理解が足らないのでもっと便利で素敵な使い方があるのだろうか?
ああ!今日も眠れそうにないなw
138行目の sorted メソッドがしっくりこないけどどうしたらいいのか解らないので適当にやったら期待通りに動いてしまった。( ̄。 ̄;)
さて、長くなるけど一応このプログラムの実行結果を載せておきます。
run:
<– MyTeam 全員表示 –>
ほげほげ たこたろう, 32歳, Gender: MALE, Breast Size: 90, FightingPower: 100
壇蜜, 32歳, Gender: FEMALE, Breast Size: 90, FightingPower: 99
北川 景子, 26歳, Gender: FEMALE, Breast Size: 78, FightingPower: 80
綾瀬 はるか, 27歳, Gender: FEMALE, Breast Size: 88, FightingPower: 85
佐々木 希, 25歳, Gender: FEMALE, Breast Size: 80, FightingPower: 85
剛力 彩芽, 20歳, Gender: FEMALE, Breast Size: 77, FightingPower: 75
川口 春奈, 18歳, Gender: FEMALE, Breast Size: 75, FightingPower: 70
堀北 真希, 24歳, Gender: FEMALE, Breast Size: 78, FightingPower: 76
武井 咲, 19歳, Gender: FEMALE, Breast Size: 76, FightingPower: 66
石原 さとみ, 26歳, Gender: FEMALE, Breast Size: 82, FightingPower: 89
深田 恭子, 30歳, Gender: FEMALE, Breast Size: 90, FightingPower: 84
<—MyBestMember –>
北川 景子, 26歳, Gender : FEMALE, Breast Size : 78, FightingPower : 80
綾瀬 はるか, 27歳, Gender : FEMALE, Breast Size : 88, FightingPower : 85
佐々木 希, 25歳, Gender : FEMALE, Breast Size : 80, FightingPower : 85
剛力 彩芽, 20歳, Gender : FEMALE, Breast Size : 77, FightingPower : 75
堀北 真希, 24歳, Gender : FEMALE, Breast Size : 78, FightingPower : 76
武井 咲, 19歳, Gender : FEMALE, Breast Size : 76, FightingPower : 66
石原 さとみ, 26歳, Gender : FEMALE, Breast Size : 82, FightingPower : 89
<– MyBestMember FightingPower 昇順ソート –>
66
75
76
80
85
85
89
<– MyBestMember FightingPower 最大値を表示 –>
89
<– MyBeatMember を FightingPower 詳細昇順ソート –>
武井 咲, 19歳, Gender : FEMALE, Breast Size : 76, FightingPower : 66
剛力 彩芽, 20歳, Gender : FEMALE, Breast Size : 77, FightingPower : 75
堀北 真希, 24歳, Gender : FEMALE, Breast Size : 78, FightingPower : 76
北川 景子, 26歳, Gender : FEMALE, Breast Size : 78, FightingPower : 80
綾瀬 はるか, 27歳, Gender : FEMALE, Breast Size : 88, FightingPower : 85
佐々木 希, 25歳, Gender : FEMALE, Breast Size : 80, FightingPower : 85
石原 さとみ, 26歳, Gender : FEMALE, Breast Size : 82, FightingPower : 89
BUILD SUCCESSFUL (total time: 0 seconds)
では、そろそろ寝ようかな。(眠れたら幸せになれるかも)