Java
Java
Java8 では Arrays.parallelSort() が導入される予定だ。
どうやら Fork/Join Framework を使っているようです。
今まではプリミティブ型はデュアルピボットのクイックソートで参照型は Tim ソートだったような記憶があります。
この記憶の信憑性はかなり低いので間違っていても怒らないでくださいね(^_^;)
そこで早速試してみることにします。
コードはシンプルなソートです。
jp\yucchi\parallelsort\ParallelSort.java |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
package jp.yucchi.parallelsort; import java.util.Arrays; import java.util.Date; import java.util.Random; public class ParallelSort { private static final int TARGET_SIZE = 500_000_000; private static final int LOOP_SIZE = 20; private static long startTime; private static long time; private static long avgTime; private static long sumTime; private static int count; private static long avg4p; public static void main(String[] args) { Random random = new Random(new Date().getTime()); int[] source = new int[TARGET_SIZE]; int[] copy; for (int i = 0; i < TARGET_SIZE; ++i) { source[i] = random.nextInt(TARGET_SIZE); } for (int i = 0; i < LOOP_SIZE; ++i) { copy = Arrays.copyOfRange(source, 0, TARGET_SIZE); startTime = System.nanoTime(); Arrays.parallelSort(copy); time = System.nanoTime() - startTime; System.out.println(i + 1 + "回目 : Arrays.parallelSortの処理時間は、" + (int) (time * 1e-9) / 3_600 + "時間" + (int) ((time * 1e-9) / 60) % 60 + "分" + (int) (time * 1e-9 % 60) + "秒" + Double.toString((time * 1e-9 % 60) % 1).substring(2) + "\n"); if (i > 9) { sumTime += time; count++; } } avgTime = sumTime / count; System.out.println("<----- Arrays.parallelSortの平均処理時間は、" + (int) (avgTime * 1e-9) / 3_600 + "時間" + (int) ((avgTime * 1e-9) / 60) % 60 + "分" + (int) (avgTime * 1e-9 % 60) + "秒" + Double.toString((avgTime * 1e-9 % 60) % 1).substring(2) + " ----->\n"); avgTime = 0; count = 0; sumTime = 0; for (int i = 0; i < LOOP_SIZE; ++i) { copy = Arrays.copyOfRange(source, 0, TARGET_SIZE); startTime = System.nanoTime(); Arrays.sort(copy); time = System.nanoTime() - startTime; System.out.println(i + 1 + "回目 : Arrays.sortの処理時間は、" + (int) (time * 1e-9) / 3_600 + "時間" + (int) ((time * 1e-9) / 60) % 60 + "分" + (int) (time * 1e-9 % 60) + "秒" + Double.toString((time * 1e-9 % 60) % 1).substring(2) + "\n"); if (i > 9) { sumTime += time; count++; } } avgTime = sumTime / count; System.out.println("<----- Arrays.sortの平均処理時間は、" + (int) (avgTime * 1e-9) / 3_600 + "時間" + (int) ((avgTime * 1e-9) / 60) % 60 + "分" + (int) (avgTime * 1e-9 % 60) + "秒" + Double.toString((avgTime * 1e-9 % 60) % 1).substring(2) + " ----->\n"); } } |
全てのソート時間の取得と表示、そして11回目からのソート処理平均時間の取得と表示をそれぞれ
Arrays.parallelSort() と Arrays.sort() で実行してます。
このプログラムの実行結果は概ね予測できますが下記に実行結果を貼っておきます。
1回目 : Arrays.parallelSortの処理時間は、0時間0分4秒4152691810000002
2回目 : Arrays.parallelSortの処理時間は、0時間0分3秒1656751470000004
3回目 : Arrays.parallelSortの処理時間は、0時間0分3秒4398564410000003
4回目 : Arrays.parallelSortの処理時間は、0時間0分3秒18688716800000016
5回目 : Arrays.parallelSortの処理時間は、0時間0分3秒4902016290000004
6回目 : Arrays.parallelSortの処理時間は、0時間0分3秒1557479500000003
7回目 : Arrays.parallelSortの処理時間は、0時間0分3秒5248610990000002
8回目 : Arrays.parallelSortの処理時間は、0時間0分3秒21521467700000008
9回目 : Arrays.parallelSortの処理時間は、0時間0分3秒4352946820000003
10回目 : Arrays.parallelSortの処理時間は、0時間0分3秒176553014
11回目 : Arrays.parallelSortの処理時間は、0時間0分3秒5098383400000004
12回目 : Arrays.parallelSortの処理時間は、0時間0分3秒2292058370000003
13回目 : Arrays.parallelSortの処理時間は、0時間0分3秒4357429300000004
14回目 : Arrays.parallelSortの処理時間は、0時間0分3秒20676435400000015
15回目 : Arrays.parallelSortの処理時間は、0時間0分3秒45285167800000004
16回目 : Arrays.parallelSortの処理時間は、0時間0分3秒2242083810000004
17回目 : Arrays.parallelSortの処理時間は、0時間0分3秒4621416820000004
18回目 : Arrays.parallelSortの処理時間は、0時間0分3秒5754989530000003
19回目 : Arrays.parallelSortの処理時間は、0時間0分3秒500453534
20回目 : Arrays.parallelSortの処理時間は、0時間0分3秒21473901200000034
<—– Arrays.parallelSortの平均処理時間は、0時間0分3秒3811444700000002 —–>
1回目 : Arrays.sortの処理時間は、0時間0分48秒9387049350000041
2回目 : Arrays.sortの処理時間は、0時間0分48秒9633070610000019
3回目 : Arrays.sortの処理時間は、0時間0分49秒015938085000001934
4回目 : Arrays.sortの処理時間は、0時間0分48秒9707528720000056
5回目 : Arrays.sortの処理時間は、0時間0分49秒2902336700000063
6回目 : Arrays.sortの処理時間は、0時間0分48秒9888089870000059
7回目 : Arrays.sortの処理時間は、0時間0分48秒9633770900000016
8回目 : Arrays.sortの処理時間は、0時間0分48秒9997757110000052
9回目 : Arrays.sortの処理時間は、0時間0分48秒9295900030000013
10回目 : Arrays.sortの処理時間は、0時間0分49秒08955452700000421
11回目 : Arrays.sortの処理時間は、0時間0分50秒13118777600000442
12回目 : Arrays.sortの処理時間は、0時間0分49秒8455564950000038
13回目 : Arrays.sortの処理時間は、0時間0分49秒24517728500000402
14回目 : Arrays.sortの処理時間は、0時間0分49秒12246824000000345
15回目 : Arrays.sortの処理時間は、0時間0分48秒901129044000001
16回目 : Arrays.sortの処理時間は、0時間0分49秒40450923900000646
17回目 : Arrays.sortの処理時間は、0時間0分50秒7024559510000046
18回目 : Arrays.sortの処理時間は、0時間0分49秒7857455720000033
19回目 : Arrays.sortの処理時間は、0時間0分50秒1460985550000018
20回目 : Arrays.sortの処理時間は、0時間0分51秒37098508900000127
<—– Arrays.sortの平均処理時間は、0時間0分49秒8655313240000027 —–>
Arrays.parallelSort() が3秒前半のスコアに対して Arrays.sort() は、ほぼ 50 秒かかってます。
予想通り Arrays.parallelSort() が圧倒的に高速ですね。(^_^)
その秘密は NetBeans のプロファイラで確認しました。
内部で Fork/Join Framework が使われてるのが確認されました。
Java は並行処理を簡単に実行できるようにいろいろがんばって作られてるようです。
ちなみに、アレイのサイズを21億個まで増大させたときのプログラムの実行結果は次のようになりました。
1回目 : Arrays.parallelSortの処理時間は、0時間0分26秒7820320810000005
2回目 : Arrays.parallelSortの処理時間は、0時間0分14秒215850219
3回目 : Arrays.parallelSortの処理時間は、0時間0分15秒21248125400000006
4回目 : Arrays.parallelSortの処理時間は、0時間0分14秒17695699800000142
5回目 : Arrays.parallelSortの処理時間は、0時間0分15秒21644380900000115
6回目 : Arrays.parallelSortの処理時間は、0時間0分14秒13889982600000117
7回目 : Arrays.parallelSortの処理時間は、0時間0分15秒3859477300000016
8回目 : Arrays.parallelSortの処理時間は、0時間0分14秒15733845600000151
9回目 : Arrays.parallelSortの処理時間は、0時間0分15秒042537343000001115
10回目 : Arrays.parallelSortの処理時間は、0時間0分14秒10847939100000126
11回目 : Arrays.parallelSortの処理時間は、0時間0分15秒31738622100000136
12回目 : Arrays.parallelSortの処理時間は、0時間0分14秒09331228100000111
13回目 : Arrays.parallelSortの処理時間は、0時間0分15秒23933288000000097
14回目 : Arrays.parallelSortの処理時間は、0時間0分14秒09788163900000058
15回目 : Arrays.parallelSortの処理時間は、0時間0分15秒2869010420000002
16回目 : Arrays.parallelSortの処理時間は、0時間0分14秒1130110920000007
17回目 : Arrays.parallelSortの処理時間は、0時間0分15秒037243257000000085
18回目 : Arrays.parallelSortの処理時間は、0時間0分14秒1627590560000005
19回目 : Arrays.parallelSortの処理時間は、0時間0分15秒16421842200000114
20回目 : Arrays.parallelSortの処理時間は、0時間0分14秒3338693370000012
<—– Arrays.parallelSortの平均処理時間は、0時間0分14秒6845915220000016 —–>
1回目 : Arrays.sortの処理時間は、0時間3分46秒10638811700002293
2回目 : Arrays.sortの処理時間は、0時間3分45秒5415704870000013
3回目 : Arrays.sortの処理時間は、0時間3分44秒14708787200001439
4回目 : Arrays.sortの処理時間は、0時間3分44秒28659846600001515
5回目 : Arrays.sortの処理時間は、0時間3分44秒2646577520000051
6回目 : Arrays.sortの処理時間は、0時間3分43秒6922063590000107
7回目 : Arrays.sortの処理時間は、0時間3分43秒25756076300001496
8回目 : Arrays.sortの処理時間は、0時間3分44秒48740214200000764
9回目 : Arrays.sortの処理時間は、0時間3分42秒6569463620000136
10回目 : Arrays.sortの処理時間は、0時間3分42秒32911070500000505
11回目 : Arrays.sortの処理時間は、0時間3分41秒22716906600001607
12回目 : Arrays.sortの処理時間は、0時間3分41秒819911870000027
13回目 : Arrays.sortの処理時間は、0時間3分41秒3822147500000028
14回目 : Arrays.sortの処理時間は、0時間3分41秒0946705690000158
15回目 : Arrays.sortの処理時間は、0時間3分42秒02558318500001633
16回目 : Arrays.sortの処理時間は、0時間3分51秒4318844270000284
17回目 : Arrays.sortの処理時間は、0時間3分52秒048210971000003155
18回目 : Arrays.sortの処理時間は、0時間3分52秒01929548700002215
19回目 : Arrays.sortの処理時間は、0時間3分52秒04963036800000964
20回目 : Arrays.sortの処理時間は、0時間3分52秒09709150600002658
<—– Arrays.sortの平均処理時間は、0時間3分46秒7195662190000007 —–>
Java8 の正式リリースが待ち遠しいです!
ちなみに 9 月 9 日にリリース予定だったのですが、どうやら遅れそうです。
ツイッター上では 2014 年になるとか・・・つぶやかれていました。
今のうちにもっと情報集めて Java8 をしっかり楽しめるようにがんばってみるとしよう。(*^o^*)
TAGS: Java |
2013年4月21日10:54 AM |
Java
今日も Java8 の新機能に慣れるべくいつものようにネットサーフィンで得た情報を試してみます。
今回は前回チラッと現れたSupplier インターフェイスと Constructor References をためしてみようと思います。
非常に簡単でシンプルな内容なのです。ラムダ式を使う方法とコンストラクターリファレンスを使う方法を記述してます。
それを Supplier インターフェイスの get() メソッドで取得してそれぞれのインスタンスメソッドを実行させているだけです。
特に難しいところは無さそうですが、この使い分けのシチュエーションは微妙かもしれませんね。
では、プログラムのコードです。
mylambdaexamples_3\Airplane.java |
|
package mylambdaexamples_3; class Airplane { void pilot() { System.out.println("飛行機を操縦します。"); } } |
mylambdaexamples_3\JetAirplane.java |
|
package mylambdaexamples_3; class JetAirplane extends Airplane { @Override void pilot() { System.out.println("ジェット機を操縦します。"); } } |
mylambdaexamples_3\MyLambdaExamples_3.java |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
package mylambdaexamples_3; import java.util.function.Supplier; public class MyLambdaExamples_3 { public static void main(String[] args) { // Lambda Expression pilot(() -> new Airplane()); pilot(() -> new JetAirplane()); // Constructor References pilot(Airplane::new); pilot(JetAirplane::new); } static void pilot(Supplier<? extends Airplane> supplier) { Airplane airPlane = supplier.get(); airPlane.pilot(); } } |
実行結果は次のようになります。
飛行機を操縦します。
ジェット機を操縦します。
飛行機を操縦します。
ジェット機を操縦します。
Java の学習の初めのころにこのような感じのをやったようなデジャブを感じます。
いちおう JavaDoc をサラッと見てみます。
いつものように優秀な翻訳支援ソフトに活躍してもらいます。(>_<。)
Supplier
java.util.function
@FunctionalInterface
public interface Supplier<T>
A supplier of objects. The result objects are either created during the invocation of Supplier.get
or by some prior action.
パラメータ:
T
– The type of objects returned by get
日付:
1.8
オブジェクトのサプライヤ。 オブジェクトが Supplier.get の呼出しの間に、あるいは若干の事前のアクションによってあるいは作り出されるという結果。
パラメータ: get によりオブジェクトのタイプが返される。
get()
java.util.function.Supplier
public T get()
Returns an object.
戻り値:
an object
オブジェクトを返します。
特に難しいところは無さそうですね。強いて言うなら英語の JavaDoc か・・・
そういうことでそろそろお約束の時間です。
この「もっと Lambda 」シリーズは、インターネット上で得た情報を元にそれを少し変更しているだけです。
悲しいことにその情報源は英語なので詳しい内容はわかりません。
よって私の推測で解釈された内容となってますので間違いがあると思います。
Java8 もまだ build86 を使用していますので API の変更により記述方法が変わるかもしれません。
早く正式リリースされて日本語でこの超便利で素敵な新機能を勉強したい今日この頃です。
TAGS: Java |
2013年4月20日4:44 AM |
Java
今日も Java8 の新機能に慣れるべくネットから情報収集したものを試してみます。
今回の情報源も外国語のサイトなので詳しいことは理解できませんでしたが雰囲気だけでも感じてみたいと思います。(なんのこっちゃ?
ってな訳で今回は「JDK8 Lambda その他いろいろ なんでもいいから動かしてみる」シリーズでもお馴染みの Optional です。
前はストリームでゴニョゴニョしていたので今回は素のままで。
シンプルなコードなのでだいたいのことは解るような気がします。
mylambdaexamples_2\Person.java |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
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 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
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> 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<Person> found = find("はるか", person); found.ifPresent(f -> { System.out.println(f.getLastName()); }); // いない Optional<Person> found2 = find("はる", person); System.out.println(found2.orElse(new Person("名無しの", "権兵衛", LocalDate.of(2013, 4, 1), Person.Sex.MALE)).getLastName()); // いない Optional<Person> found3 = find("るか", person); System.out.println(found3.orElseGet(() -> { return new Person("日本", "太郎", LocalDate.of(2002, 4, 18), Person.Sex.MALE); }).getLastName()); } private static Optional<Person> find(String lastName, List<Person> 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 の変更により記述方法が変わるかもしれません。
早く正式リリースされて日本語でこの超便利で素敵な新機能を勉強したい今日この頃です。
TAGS: Java |
2013年4月19日12:26 AM |
Java
Java8 の注目の新機能の Lambda についてなんでもいいから情報を拾い集めて動かしてみることをしています。
今回は Predicate インターフェイスと Consumer インターフェイスです。
この情報源も英語なので詳しく読むことができませんでした。
コードよりだいたいのことを理解できればと思い、参考にさせてもらってほぼ丸写しのサンプルを作りました。(^_^;
非常にシンプルなので特に説明の必要はないと思いますが JavaDoc の内容を一部コメントとして記載しておきました。
jp\yucchi\preidcate_consumer\Person.java |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
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 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
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 の変更により記述方法が変わるかもしれません。
早く正式リリースされて日本語でこの超便利で素敵な新機能を勉強したい今日この頃です。
TAGS: Java |
2013年4月14日4:58 AM |
Java
今日もはじまります。
JDK8 Lambda その他いろいろ なんでもいいから動かしてみる 最終回です。
やっと終わるのかと思っている人もいるかもしれませんね。
では、最終回のお題は 最も一番売れた商品 を表示させてみます。
このプログラムのコードは下記のようになります。
mylambdaexamples\MyLambdaExamples.java |
114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
// 最も一番売れた商品 System.out.println("\n<-- 最も一番売れた商品 -->"); ToIntFunction<Entry<Wristwatch, List<Sale>>> toSize = (e -> e.getValue().size()); Optional<Wristwatch> mostBought; mostBought = sales.collect(groupingBy(Sale::getWristwatch)) .entrySet() .stream() .sorted(comparing(toSize).reverseOrder()) .map(Entry::getKey) .findFirst(); if (mostBought.isPresent()) { System.out.println(mostBought.get().getBrand() + " " + mostBought.get().getModel()); } |
今回もシンプルなコードで実装されてます。素敵です!(*^o^*)
116 行目で Wristwatch をキーに List<Sale> を値とし、Wristwatch ごとに売れた個数を( int 値 ) を toSize に格納、
117 行目で Optional<Wristwatch> mostBought を宣言
118 行目から sales ストリームを Sale クラスの getWristwatch() メソッドで取得した wristwatch でグルーピングしてリダクションし、
マップに格納されているマッピングのセットビューを返し、それをストリームにしなおして toSize を引数にして sorted() メソッドでソートしたものをリバースさせ、
map() メソッドの引数にエントリに対応するキーを渡してストリームを構築しなして、findFirst() メソッドで最初の要素(最も一番売れた商品)を取得。
124 行目で mostBought に最初の要素があるか isPresent() メソッドで判定し、
125 行目でその要素のブランド名とモデル名を表示させてます。
ちょっとややこしく感じるかもしれませんがこれだけの処理をこれだけ簡潔に記述できるって素敵だと思いませんか?
疑り深いあなたの為に実行結果は次のようになります。
<– 最も一番売れた商品 –>
ティファニー ポーセリン
あってますね。
ちなみに、この ティファニー ポーセリン は私の好きな腕時計の一つです。
誰か持ってていらない人は私に無償でプレゼントしてください!
壊れてて動かなくても OK です!
おっと、いけない。かなり私情がはいってしまった。(;´∀`)
ついでにと言ってはなんですけど最終回ということで違う方法も紹介しておきます。
mylambdaexamples\MyLambdaExamples.java |
130 131 132 133 134 135 136 137 138 139 140 141
|
// 最も一番売れた商品 System.out.println("\n<-- 最も一番売れた商品 -->"); ToIntFunction<Entry<Wristwatch, List<Sale>>> _toSize = (e -> e.getValue().size()); sales.collect(groupingBy(Sale::getWristwatch)) .entrySet() .stream() .sorted(comparing(_toSize).reverseOrder()) .map(Entry::getKey) .limit(1) .forEach(e -> { System.out.println(e.brand + " " + e.model); }); |
こちらのほうが私的にはすっきりしますね。
ただ、要素が無い場合のことは考えてないですが・・・
こちらだと limit() メソッドの引数を変えるだけでベスト3とか表示させることも可能です。
まだまだ他にも方法はあるかもしれませんがはっきりいえることは Java8 はコレクションがらみが非常に強化されるってことですね!
それでは最後のお約束です。
この「JDK8 Lambda その他いろいろ なんでもいいから動かしてみる」シリーズはインターネット上で得た情報を元にそれを少し変更しているだけです。
悲しいことにその情報源は英語なので詳しい内容はわかりません。
よって私の推測で解釈された内容となってますので間違いがあると思います。
Java8 もまだ build83 を使用していますので API の変更により記述方法が変わるかもしれません。
早く正式リリースされて日本語でこの超便利で素敵な新機能を勉強したい今日この頃です。
TAGS: Java |
2013年4月10日11:36 AM |
« 古い記事
新しい記事 »