Java
Java
モンテカルロ法という乱数シュミレーションで円周率を導き出してみます。
半径 r の円の面積は PI * r^2 ですよね。
半径 r を 1 とした円を中心から十文字に四等分した右上の部分を使って円周率を求めます。
円の中心から辺の長さ 1 の正方形を重ねます。
正方形の中には4等分された右上の部分の扇形の円がきっちり半径 1 の状態であります。
この時 x 軸、y 軸の 1 の位置は重ねた正方形の辺の長さ 1 になりますね。
よって、正方形の面積 : 扇の面積 = 1 : PI / 4 となります。
したがって PI を求める式は次のようになります。
PI = 4 * 扇の面積/正方形の面積
プログラムは乱数を使ってこの正方形の中にたくさんの針を落とします。
針の落ちた位置が扇の中か外かで円周率を求めていくという力技の方法です。
落とす針の数が多いほど精度は上がる理屈ですが処理時間も増えてしまいます。
とりあえず試してみましょう。
jp\yucchi\montecarlo_pi\Montecarlo_PI.java |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
package jp.yucchi.montecarlo_pi; import java.util.Random; public class Montecarlo_PI { private static final int NEEDLE = 100000000; public static void main(String[] args) { int hitCount = 0; double x, y, pi; for (int i = 0; i < NEEDLE; i++) { x = Math.random(); y = Math.random(); if (Math.pow(x, 2.0) + Math.pow(y, 2.0) < 1.0) { hitCount++; } } pi = 4.0 * hitCount / NEEDLE; System.out.println("Mathクラスによる円周率は " + Math.PI); System.out.println("モンテカルロ法による円周率は " + pi); } } |
実行結果は次のようになりました。
run:
Mathクラスによる円周率は 3.141592653589793
モンテカルロ法による円周率は 3.14185944
構築成功 (合計時間: 9 秒)
何回かやって見たのですが小数点以下3位くらいまでの精度しかでませんでした。
精度を上げるにはこの処理を数回(数万回?)繰り返して平均をとればいいのかなぁ・・・?
TAGS: Java |
2012年6月11日8:40 PM |
Java
Lambda のことをいろいろ軽く調べてきました。
Swing を使った GUI アプリでも Lambda は重宝されそうですね。
それでは Lambda を使った簡単な Swing アプリを作ってみました。
jp\yucchi\Swing_Lambda_1.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
|
package jp.yucchi; import javax.swing.JOptionPane; public class Swing_Lambda_1 extends javax.swing.JFrame { public Swing_Lambda_1() { initComponents(); } @SuppressWarnings("unchecked") private void initComponents() { jButton1 = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); jButton1.setText("押してみて!"); jButton1.addActionListener(e -> { JOptionPane.showMessageDialog(null, "こんにちわ~ (^_^)v"); }); getContentPane().add(jButton1, java.awt.BorderLayout.CENTER); pack(); setLocationRelativeTo(null); } public static void main(String args[]) { java.awt.EventQueue.invokeLater(() -> { new Swing_Lambda_1().setVisible(true); }); } private javax.swing.JButton jButton1; } |
これまでのコードと違う部分が2カ所ありますね。
Lambda を使うと無名クラスの生成記述を省略できてしまうんですね~(^_-)-☆
それでは本当にこれで動くのか確認してみます。
おおっ!動いてますね(^_^)v
Lambda を使った難しいことは解りませんがこんな簡単で便利なことは好きです!
少しずつ Lambda に慣れて JDK 8 を楽しめるようになれるといいなと思う今日この頃です。
TAGS: Java |
2012年6月6日8:37 PM |
Java
はじめての Lambda シリーズも4回目となりました。
今回は Method Reference を使ってみることにします。
Method Reference って名前のとおりメソッド参照です。
メソッドに対する参照だけです。
よって、はじめての Lambda vol.2 でのサンプルコードの最大値を求める部分を
Method Reference に置き換えることができます。
下記コードのように非常に簡潔になります。(^_^)v
jp\yucchi\hello_lambda_2\Hello_Lambda_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
|
package jp.yucchi.hello_lambda_2; import java.util.ArrayList; import java.util.List; public class Hello_Lambda_2 { public static void main(String[] args) { List<Lady> ladies = new ArrayList<>(); ladies.add(new Lady(80, 20)); ladies.add(new Lady(70, 14)); ladies.add(new Lady(85, 30)); ladies.add(new Lady(90, 24)); ladies.add(new Lady(100, 10)); int maxBust = ladies.filter(l -> l.age > 15 && l.age < 26) .map(l -> l.bustSize) //.reduce(0, (left, right) -> Math.max(left, right)); // Method Reference を使うように変更 .reduce(0, Math::max); System.out.println("16歳以上、26歳未満で一番大きな胸のサイズは" + maxBust + "です。"); } private static class Lady { int bustSize; int age; public Lady(int bustSize, int age) { this.bustSize = bustSize; this.age = age; } } } |
Math::max の部分が Method Reference を利用したコードです。
こんなにすっきりしたコードで本当にちゃんと動くのか?
試してみました。

おおっ! ちゃんと動いてるじゃないか!
一時期、Method Reference に :: と # どちらを使うかで熱い議論がなされていた。(今も?)
Java™ Platform, Standard Edition 8 Developer Preview with Lambda Support b 39 では
:: (ダブルコロン)が採用されているようです。
Java 8 で Lambda が実装されたら馴染みのない素敵なコードを見ることができるような気がします。
TAGS: Java |
2012年6月6日9:16 AM |
Java
JDK 8 で採用される予定の Lambda についていろいろ調べているんですが
今回は Virtual Extension Methods または Defender Methods と言われている?
新たな(都合の良い?)ものについて調べてみました。
インタフェースを実装する場合 JDK 7 までは全てのメソッドを実装する必要でしたよね。
JDK 8 ではデフォルト実装を定義できるらしいんです。
具体的には次のプログラムを見てください。
jp\yucchi\virtual_extension_method_1\Virtual_Extension_Method_1.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
|
package jp.yucchi.virtual_extension_method_1; interface Hello { void sayHello(); void sayHelloDefaulter() default { System.out.println("Default from interface : Hello World!"); } } public class Virtual_Extension_Method_1 { public static void main(String[] args) { HelloImplementer helloImpl = new HelloImplementer(); helloImpl.sayHello(); helloImpl.sayHelloDefaulter(); } } class HelloImplementer implements Hello { @Override public void sayHello() { System.out.println("Hello World!"); } } |
今までだったら sayHelloDefalter() メソッドを HelloImplementer クラスが実装していないので
コンパイルエラーになったはずですよね。
JDK 8 ではメソッドに defalt キーワードを付けることによって
デフォルト実装されます!
実際に動かしてみました。

ちゃんと動いてます。
もちろん、デフォルト実装されたメソッドも!
ここでちょっと疑問が・・・
デフォルト実装されたメソッドってオーラーライドできるの?
コードを次のように変更しました。
jp\yucchi\virtual_extension_method_1\Virtual_Extension_Method_1.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
|
<font size="4"><span class="keyword-directive">package</span> jp.yucchi.virtual_extension_method_1; <span class="keyword-directive">interface</span> <span class="ST0">Hello</span> { <span class="keyword-directive">void</span> <span class="ST0">sayHello</span>(); <span class="keyword-directive">void</span> <span class="ST0">sayHelloDefaulter</span>() <span class="keyword-directive">default</span> { System.<span class="ST1">out</span>.println(<span class="character">"</span><span class="character">Default from interface : Hello World!</span><span class="character">"</span>); } } <span class="keyword-directive">public</span> <span class="keyword-directive">class</span> <span class="ST0">Virtual_Extension_Method_1</span> { <span class="keyword-directive">public</span> <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> <span class="ST2">main</span>(String[] args) { HelloImplementer helloImpl = <span class="keyword-directive">new</span> HelloImplementer(); helloImpl.sayHello(); helloImpl.sayHelloDefaulter(); } } <span class="keyword-directive">class</span> <span class="ST0">HelloImplementer</span> <span class="keyword-directive">implements</span> Hello { @Override <span class="keyword-directive">public</span> <span class="keyword-directive">void</span> <span class="ST0">sayHello</span>() { System.<span class="ST1">out</span>.println(<span class="character">"</span><span class="character">Hello World!</span><span class="character">"</span>); } @Override <span class="keyword-directive">public</span> <span class="keyword-directive">void</span> <span class="ST0">sayHelloDefaulter</span>(){ System.<span class="ST1">out</span>.println(<span class="character">"</span><span class="character">Defautler overridden from class : Hello World!</span><span class="character">"</span>); } }</font> |
それでは実行させてみます。

ちゃんとオーバーライドされてますね!(^^)
なかなか面白いですね。
この Virtual Extension Methods は Lambda を実装するのにおまけではなく
必要不可欠な実装らしいです。
私は Lambda のことはまだほとんど解りませんが JDK 8 がリリースされるのが少し楽しみになってきました。(*^_^*)
TAGS: Java |
2012年5月25日5:56 AM |
Java
今朝から作ったプログラムを Lambda を使うように変更しようといろいろ調べてた。
そしたら以前 Fork/Join フレームワークについて調べていたときに発見したコードを目にした。
確か IBM のサイトにあった記事だがどうやらちょくちょくサンプルにあがってくるコードらしい。
日本語で Lambda の解説をしてくれているサイトにもあった。
ある年の学生のハイスコアを見つけ出すプログラムだ。
それを参考にしてこんなプログラムを組んでみた。
一番大きなバストを調べるプログラムだ。
ただし年齢制限を設けた。
16歳以上、26歳未満だ。
Java 7 でのコードは次のようになります。
jp\yucchi\hello_lambda_2\Hello_Lambda_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
|
package jp.yucchi.hello_lambda_2; import java.util.ArrayList; import java.util.List; public class Hello_Lambda_2 { public static void main(String[] args) { List<Lady> ladies = new ArrayList<>(); ladies.add(new Lady(80, 20)); ladies.add(new Lady(70, 14)); ladies.add(new Lady(85, 30)); ladies.add(new Lady(90, 24)); ladies.add(new Lady(100, 10)); int maxBust = 0; for (Lady l : ladies) { if (l.age > 15 && l.age < 26) { if (l.bustSize > maxBust) { maxBust = l.bustSize; } } } System.out.println("16歳以上、26歳未満で一番大きな胸のサイズは" + maxBust + "です。"); } private static class Lady { int bustSize; int age; public Lady(int bustSize, int age) { this.bustSize = bustSize; this.age = age; } } } |
実行結果は
run:
16歳以上、26歳未満で一番大きな胸のサイズは90です。
構築成功 (合計時間: 0 秒)
期待通りの結果となります。
次にこれを Lambda を使ってみます。
jp\yucchi\hello_lambda_2\Hello_Lambda_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
|
package jp.yucchi.hello_lambda_2; import java.util.ArrayList; import java.util.List; public class Hello_Lambda_2 { public static void main(String[] args) { List<Lady> ladies = new ArrayList<>(); ladies.add(new Lady(80, 20)); ladies.add(new Lady(70, 14)); ladies.add(new Lady(85, 30)); ladies.add(new Lady(90, 24)); ladies.add(new Lady(100, 10)); int maxBust = ladies.filter(l -> l.age > 15 && l.age < 26) .map(l -> l.bustSize) .reduce(0, (left, right) -> Math.max(left, right)); System.out.println("16歳以上、26歳未満で一番大きな胸のサイズは" + maxBust + "です。"); } private static class Lady { int bustSize; int age; public Lady(int bustSize, int age) { this.bustSize = bustSize; this.age = age; } } } |
なんか見慣れないものがちらほらありますね。
実行結果は

Good! (^^)
この部分が JDK 8 の新兵器 Lambda ですね。
|
int maxBust = ladies.filter(l -> l.age > 15 && l.age < 26) .map(l -> l.bustSize) .reduce(0, (left, right) -> Math.max(left, right)); |
見慣れないメソッドの正体は
filter メソッド : コレクションの要素のフィルタリングをする優れものです。
引数の Predicate オブジェクトの eval メソッドの戻り値が true の要素だけをフィルタリングします。
map メソッド : 新しいコレクションを作り直すメソッドです。
Mapper オブジェクトの map メソッドの戻り値を新たな要素としたコレクションを作ります。
reduce メソッド : 要素を減らして、最終的に一つにするためのメソッドです。
以上のように Lambda を使うポイントを少しだけ知ったつもりになった。(^0^;)
もっと詳しく知りたい方は参考にさせていただいたというよりは、まるっといただいたサイトを紹介します。
Project Lambda
こちらのサイトが勉強になります。
ただし、上記のプログラムでパラレル処理をする方法も載っていましたが
なんと エラー になってしまいます。
Lambda はまだ開発途中なので紹介したサイトの情報もいつまで有効なのかは解りません。
日本語の情報はまだまだ少ないようなので、英語が得意な方は英語サイトをググって情報収集したほうがいいかもです。
TAGS: Java |
2012年5月20日10:20 PM |
« 古い記事
新しい記事 »