2013
Java NetBeans
今日も Java8 がらみのネタです。
今回はちょっといつもと違って私が愛用している高機能な開発環境について少しだけ触れてみたいと思います。
日本でも人気赤丸急上昇中の NetBeans です。
今は Java8 を試すのに開発版を使っています。
注目の Lambda にも徐々にですが対応してます。
以前にも少し紹介したので今回は逆パターンを紹介します。
つまり、Lambda を使わない無名インナークラスを使用する標準的な(?)コードに変換するという試みです。
サンプルは前回のエントリーの JavaCury.java です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
package jp.yucchi.javacurry; import java.util.function.Function; import java.util.function.BiFunction; public class JavaCurry { public static void main(String[] args) { Function<String, Function<String, String>> house = java -> curry -> java + curry; System.out.println(house.apply("ジャワ").apply("カレー")); BiFunction<String, String, String> h = (java, curry) -> java + curry; System.out.println(h.apply("ジャワ", "カレー")); Function<String, Function<String, Function<String, String>>> house2 = java -> curry -> level -> java + curry + level; System.out.println(house2.apply("ジャワ").apply("カレー").apply("甘口")); Function<String,BiFunction<String, String, String>> h2 = java -> (curry, level) -> java +curry + level; System.out.println(h2.apply("ジャワ").apply("カレー","辛口")); } } |
では、実際にどのように変換されるのかスクリーンショットを撮ってみました。
10 行目の Lambda 式を変換してみます。
見事に変換されました。さすが NetBeans !
では、もう少し試してみましょう。
この Lambda 式は引数の型が省略されてます。
ちまたでは Lambda 式の型省略は企業によっては禁止されるんじゃないかと噂されてます。
それでか、どうかは解りませんが省略された型をコードに追加する機能もあります。
さっそく試してみましょう。
省略された型がちゃんと追加され表示されてますね。(^_^)
ついでに Lambda 式を複数行で書く場合を試してみます。
ちゃんと return 文もつくられてますね。
さすがです!
では、無名クラスを使うコードに変換してます。
全ての Lambda 式を無名クラスを使うコードに変換したプログラムはこのようになりました。
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
|
package jp.yucchi.javacurry; import java.util.function.Function; import java.util.function.BiFunction; public class JavaCurry { public static void main(String[] args) { Function<String, Function<String, String>> house = new Function<String, Function<String, String>>() { @Override public Function<String, String> apply(String java) { return new Function<String, String>() { @Override public String apply(String curry) { return java + curry; } }; } }; System.out.println(house.apply("ジャワ").apply("カレー")); BiFunction<String, String, String> h = new BiFunction<String, String, String>() { @Override public String apply(String java, String curry) { return java + curry; } }; System.out.println(h.apply("ジャワ", "カレー")); Function<String, Function<String, Function<String, String>>> house2 = new Function<String, Function<String, Function<String, String>>>() { @Override public Function<String, Function<String, String>> apply(String java) { return new Function<String, Function<String, String>>() { @Override public Function<String, String> apply(String curry) { return new Function<String, String>() { @Override public String apply(String level) { return java + curry + level; } }; } }; } }; System.out.println(house2.apply("ジャワ").apply("カレー").apply("甘口")); Function<String, BiFunction<String, String, String>> h2 = new Function<String, BiFunction<String, String, String>>() { @Override public BiFunction<String, String, String> apply(String java) { return new BiFunction<String, String, String>() { @Override public String apply(String curry, String level) { return java + curry + level; } }; } }; System.out.println(h2.apply("ジャワ").apply("カレー", "辛口")); } } |
これをみると Lambda 式ってけっこうイケてるかなって思います。
ちなみに Java8 と Java8 対応の NetBeans はまだ開発中なので動作が完全ではありません。
でも、開発版でグリグリやってると開発チームの熱い思いはしっかりと伝わってきます。
きっと Java8 対応の NetBeans もいつも通り素晴らしい出来でリリースされると確信してます。(^_^)
Technorati タグ:
Java,
NetBeans
TAGS: Java,NetBeans |
2013年5月3日4:13 PM |
Java
今日はとても感動した記事があったので紹介します。
なんと日本語です!
Java 8を関数型っぽく使うためのおまじない
ちょっとおまじないの部分は私にとっては呪いの呪文のようにもとれました。(>_<。)
この記事の中でカリー化という技法が紹介されてました。
私はこの技法は初めてなので少し調べてみました。
Wikipedia では次のように解説されてました。
カリー化 (currying) とは、計算機科学分野の技法の一つ。複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること。
この技法は、クリストファー・ストレイチーにより論理学者ハスケル・カリーに因んで名付けられたが、実際に考案したのは Moses Schönfinkel とゴットロープ・フレーゲである。
f( a, b ) = c という関数 f があるときに、F( a ) = g ただし、g( b ) = c という関数 g が得られる関数 F を定義した場合、F は、f をカリー化したものである。
といことで自分でも試してみたくなりました。
決して疑ってる訳ではありません。新しい未知なるものへのあくなき好奇心からです。
ついでに、甘えと言っていた部分も自分なりに考えてみました。
いつものように未熟なコードですが以下のようにプログラムを組んでみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
package jp.yucchi.javacurry; import java.util.function.Function; import java.util.function.BiFunction; public class JavaCurry { public static void main(String[] args) { Function<String, Function<String, String>> house = java -> curry -> java + curry; System.out.println(house.apply("ジャワ").apply("カレー")); BiFunction<String, String, String> h = (java, curry) -> java + curry; System.out.println(h.apply("ジャワ", "カレー")); Function<String, Function<String, Function<String, String>>> house2 = java -> curry -> level -> java + curry + level; System.out.println(house2.apply("ジャワ").apply("カレー").apply("甘口")); Function<String,BiFunction<String, String, String>> h2 = java -> (curry, level) -> java +curry + level; System.out.println(h2.apply("ジャワ").apply("カレー","辛口")); } } |
実行結果は期待通りに次のようになりました。
ジャワカレー
ジャワカレー
ジャワカレー甘口
ジャワカレー辛口
java.util.function.BiFunction を使ってみました。
引数が多くなったときの正しい処理が解らないので適当にしたら期待通りの結果となってしまいました。
間違っている、もしくは正しい方法があるのならご教示いただければ幸いです。
そう言えば、昔 JavaHouse 高木浩光さんのホームページに Java は ジャワカレーとは関係ないという注意書きがあったような気がします。
とてもまじめそうで冗談一つ言わなそうな雰囲気を醸し出していたのでそれがジョークなのか本気なにか聞きたかった覚えがあります。
どうでもいいことだけど
思いっきり思い出した(×_×)
JavaDoc をサラッといっときましょうか。
Function
java.util.function
@FunctionalInterface
public interface Function<T,R>
Apply a function to the input argument, yielding an appropriate result. A function may variously provide a mapping between types, object instances or keys and values or any other form of transformation upon the input.
パラメータ:
T
– the type of the input to the apply
operation
R
– the type of the result of the apply
operation
日付:
1.8
apply()
java.util.function.Function
public R apply(T t)
Compute the result of applying the function to the input argument
パラメータ:
t
– the input object
戻り値:
the function result
BiFunction
java.util.function
@FunctionalInterface
public interface BiFunction<T,U,R>
Apply a function to the input arguments, yielding an appropriate result. This is the two-arity specialization of Function
. A function may variously provide a mapping between types, object instances or keys and values or any other form of transformation upon the input.
パラメータ:
T
– the type of the first argument to the apply
operation
U
– the type of the second argument to the apply
operation
R
– the type of results returned by the apply
operation
日付:
1.8
それでは、お約束の時間です。
この「もっと Lambda 」シリーズは、インターネット上で得た情報を元にそれを少し変更しているだけです。
よって私の推測で解釈された内容が部分的にありますので間違いがあると思います。
Java8 もまだ build86 を使用していますので API の変更により記述方法が変わるかもしれません。
早く正式リリースされて日本語でこの超便利で素敵な新機能を勉強したい今日この頃です。
TAGS: Java |
2013年5月1日9:02 PM |
Java
早いものでもう五月なんですね。
世間一般はゴールデンウィークなんでしょうが私はまだまだ働かなくてはいけません。
明日の夜勤(長時間)が終われば世間一般より短いけどゴールデンウィークが始まります。
だから何かイベントがあるのかって言われると何もないですね。
運転手 + 召使い + α で隙をみてゴロゴロするくらいかな。
さて、世間がゴールデンウィークに浮かれている今日この頃ですが今日のブログネタはいつもの Java8 の新機能です。
これは Twitter 上でつぶやかれていたネタです。
Twitter と言えばまだベーシック認証が使える頃に自分用のクライアントを作りかけていた時にアカウントをとってました。
ある日突然ベーシック認証が使えなくなりそれでクライアントの制作中止と Twitter 自体も使ってない状態だったのですが、何気に再開したら美味しい情報もあるので復活中です。
今回のネタはわずか 140 文字以内という制限の Twitter からいただきました。
1 から 10 まで表示させるだけのプログラムです。
|
package jp.yucchi.pkg1_to_10; import java.util.stream.Streams; public class One2Ten { public static void main(String[] args) { Streams.intRange(1, 11).forEach(System.out::println); } } |
これってありなんですかね?
実行結果は次のようになります。
1
2
3
4
5
6
7
8
9
10
All’s well that ends well. なんてねw
JavaDoc をサラッと・・・ 今回は優秀な翻訳支援ソフトを使わないのでご自分で翻訳するかお気に入りの翻訳ソフトをつかってね(ヲヒ
Streams
java.util.stream
public final class Streams extends Object
Utility methods for operating on and creating streams.
Unless otherwise stated, streams are created as sequential streams. A sequential stream can be transformed into a parallel stream by calling the parallel()
method on the created stream.
日付:
1.8
intRange()
java.util.stream.Streams
public static IntStream intRange(int start, int end)
Creates a sequential IntStream
from start
(inclusive) to end
(exclusive) by an incremental or decremental step of 1.
パラメータ:
start
– the (inclusive) initial value
end
– the exclusive upper bound
戻り値:
A sequential IntStream
for a range of int
elements
Twitter でも Good な情報を入手できることが嬉しい!
それでは、お約束の時間です。
この「もっと Lambda 」シリーズは、インターネット上で得た情報を元にそれを少し変更しているだけです。
悲しいことにその情報源は英語なので詳しい内容はわかりません。
よって私の推測で解釈された内容となってますので間違いがあると思います。
Java8 もまだ build86 を使用していますので API の変更により記述方法が変わるかもしれません。
早く正式リリースされて日本語でこの超便利で素敵な新機能を勉強したい今日この頃です。
TAGS: Java |
2013年5月1日5:46 AM |
Java
以前に 「Java 8 Date and Time API の素敵なコード」というタイトルをエントリーした。
今回はちょっとだけ感動を覚えるコードを紹介します。
なんと日本の Java Programmer の胸を熱くすること間違い無しのこれだ!
|
package jp.yucchi.displayera; import java.time.chrono.JapaneseChronology; public class DisplayEra { public static void main(String[] args) { JapaneseChronology.INSTANCE.eras().stream().forEach(System.out::println); } } |
そして我々は胸を熱くするであろう出力結果をみることになる。
Seireki
Meiji
Taisho
Showa
Heisei
慶応はさすがに無いけど十分だ!
Java8 ありがとう! 私は来年の3月18日まで首を長くして待ってるよ。(*^o^*)
TAGS: Java |
2013年4月30日9:02 PM |
Java
正式版のリリースが2014年3月18日に延期された Java8 の Lambda を今回も楽しんでみます。
いつものようにネットから情報を取得して少しコードを変えて動かしているだけの写経のようなことをやってます。
詳しいことは解らないけど慣れるってことが目的です!
今回はデザインパターンの一つである Template Method Pattern を Lambda を使って実装してみる試みです。
Template Method Pattern について知りたければグーグル先生に聞いてみたらいっぱい答えを教えてくれます。
Wikipedia では、Template Method パターン(テンプレート・メソッド・パターン)とは、GoF(Gang of Four; 4人のギャングたち)によって定義されたデザインパターンの1つである。
「振る舞いに関するパターン」に属する。Template Method パターンの目的は、ある処理のおおまかなアルゴリズムをあらかじめ決めておいて、
そのアルゴリズムの具体的な設計をサブクラスに任せることである。
そのため、システムのフレームワークを構築するための手段としてよく活用される。
と記載されてます。
今回のサンプルは現在の日付とそれぞれ30日後、60日後の日付を表示させ、ついでにつまらないメッセージも表示させるだけです。
それでは Lambda を使わないプログラムです。(Java8 の新機能の Date and Time API は使ってます。)
|
package jp.yucchi.oldtemplatemethodpattern; import java.time.LocalDate; abstract class DateCalc { void getNowDate() { System.out.println("今日は " + LocalDate.now() + " です。"); } protected abstract void getTargetDate(); void saySorry() { System.out.println("ワイルドだろぅ ごめんね。こんなサンプルで (ノД`)\n"); } } |
|
package jp.yucchi.oldtemplatemethodpattern; import java.time.LocalDate; class DateCalcImpl_1 extends DateCalc { @Override protected void getTargetDate() { System.out.println("30日後は" + LocalDate.now().plusDays(30) + " です。"); } } |
|
package jp.yucchi.oldtemplatemethodpattern; import java.time.LocalDate; class DateCalcImpl_2 extends DateCalc { @Override protected void getTargetDate() { System.out.println("60日後は" + LocalDate.now().plusDays(60) + " です。"); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
package jp.yucchi.oldtemplatemethodpattern; public class OldTemplateMethodPattern { public static void main(String[] args) { printTargetDate(new DateCalcImpl_1()); printTargetDate(new DateCalcImpl_2()); } private static void printTargetDate(DateCalcImpl_1 dateCalcImpl_1) { dateCalcImpl_1.getNowDate(); dateCalcImpl_1.getTargetDate(); dateCalcImpl_1.saySorry(); } private static void printTargetDate(DateCalcImpl_2 dateCalcImpl_2) { dateCalcImpl_2.getNowDate(); dateCalcImpl_2.getTargetDate(); dateCalcImpl_2.saySorry(); } } |
実行結果は次のようになります。
今日は 2013-04-30 です。
30日後は2013-05-30 です。
ワイルドだろぅ ごめんね。こんなサンプルで (ノД`)
今日は 2013-04-30 です。
60日後は2013-06-29 です。
ワイルドだろぅ ごめんね。こんなサンプルで (ノД`)
当然の結果で何も問題ないですね。
実際にはこのような実装は無いかと思いますが一応 Template Method Pattern の定義に沿っているのでよしとしてください。
それではこのコードを Java8 の Lambda を使うとどうなるか?
こんなになりました~! (*^o^*)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
package jp.yucchi.templatemethodpattern4lambda; import java.time.LocalDate; @FunctionalInterface public interface DateInterface { default void getNowDate() { System.out.println("今日は " + LocalDate.now() + " です。"); } void getTargetDate(); default void saySorry() { System.out.println("ワイルドだろぅ ごめんね。こんなサンプルで (ノД`)\n"); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
package jp.yucchi.templatemethodpattern4lambda; import java.time.LocalDate; public class TemplateMethodPattern4Lambda { public static void main(String[] args) { printTargetDate(() -> System.out.println("30日後は" + LocalDate.now().plusDays(30) + " です。")); printTargetDate(() -> System.out.println("60日後は" + LocalDate.now().plusDays(60) + " です。")); } private static void printTargetDate(DateInterface dateInterface) { dateInterface.getNowDate(); dateInterface.getTargetDate(); dateInterface.saySorry(); } } |
実行結果は次のようになります。
今日は 2013-04-30 です。
30日後は2013-05-30 です。
ワイルドだろぅ ごめんね。こんなサンプルで (ノД`)
今日は 2013-04-30 です。
60日後は2013-06-29 です。
ワイルドだろぅ ごめんね。こんなサンプルで (ノД`)
こちらも当然の結果で何も問題ないですね。
Lambda を使うと本当にシンプルになります。
「抽象クラスを使ってないじゃないか!」って怒らないでね。(^_^;)
DateInterface (FunctionalInterface) での Default Methods が使えるのが良いですね。
これって Java で禁じ手の多重継承を可能にするような掟破りの裏技のような気がします。
なかなか面白いですね。(^_^)
それでは、お約束の時間です。
この「もっと Lambda 」シリーズは、インターネット上で得た情報を元にそれを少し変更しているだけです。
悲しいことにその情報源は英語なので詳しい内容はわかりません。
よって私の推測で解釈された内容となってますので間違いがあると思います。
Java8 もまだ build86 を使用していますので API の変更により記述方法が変わるかもしれません。
早く正式リリースされて日本語でこの超便利で素敵な新機能を勉強したい今日この頃です。
TAGS: Java |
2013年4月30日4:07 PM |
« 古い記事
新しい記事 »