April Fools’ Day だから平凡な Java Puzzle をどうぞ

Java8 がリリースされてから1年以上経過しているので Java プログラマの皆様はガシガシとその恩恵を受けた素晴らしいコードを書いていらっしゃるでしょう。

私は未熟者なのでボチボチとチマチマ楽しんでいます。(^_^;)

そこで問題です。

このプログラムを実行すると何が表示されますか?

package jp.yucchi.hellorepeat;

import java.util.Arrays;
import java.util.List;

public class HelloRepeat {

    public static void main(String[] args) {

        List list = Arrays.asList("Hello", "World!");

        for (int i = 0; i < list.size(); i++) {
            Runnable r = () -> System.out.println(list.get(i));
            r.run();
        }
    }
}

1. Hello
    World!

2. World!
    Hello

3. コンパイルエラー

4.実行時エラー

すいません。

簡単すぎますね。

答えは 3番のコンパイルエラーです。

ラムダ式の中から外部の変数を参照する場合、その変数はfinalもしくは実質的finalでなければならない。

このルールに違反しているからです。

どうすればこのプログラムを正しく動かせるでしょうか?

それも簡単なので答えを載せておきますね!

このプログラムは for ループ文を使っているのでまずは、拡張 for ループ文で修正してみましょう。

拡張 for ループ文は少しばかりの制約はあるけど要素を先頭から順に取得するような処理には便利に使えます。

for ループ文ではインデックス取得の為に実質的ファイナルでない変数にアクセスしてコンパイルエラーになりましたが拡張 for ループ文だとそのような心配はありません。

        for (String str : list) {
            Runnable r = () -> System.out.println(str);
            r.run();
        }

あっけなく、簡単に修正できました。それでは、default void forEach(Consumer<? super T> action) を使って修正してみます。

        list.forEach(e -> {
            Runnable r = () -> System.out.println(e);
            r.run();
        }
        );

こちらの方法が Java8 っぽいので個人的には好きです。

でも内部的には、デフォルト実装の動作は次のようになっているそうです。

for (T t : this)
    action.accept(t);

つまり、こういうことなのかな?

        for (String str : list) {
            new Consumer() {
                @Override
                public void accept(String e) {
                    Runnable r = new Runnable() {
                        @Override
                        public void run() {
                            System.out.println(e);
                        }
                    };
                    r.run();
                }
            }.accept(str);
        }

以上のことを考慮してラムダ式使う場合は、forEach(Consumer<? super T> action) を使うのが良さそうですね。

これで平凡なパズルはお終いです。

Hatena タグ:

April Fools’ Day だから古典的な Java Puzzle をどうぞ

エイプリルフール用のネタを用意できなかったので古典的な Java パズルを出題します。

これは簡単なパズルなので誰でも解ると思います。

今日はエイプリルフールなので簡単に解っても難しかったと言っといてください。(ヲヒ

では問題です。

このプログラムを実行すると何が表示されますか?

package jp.yucchi.who;

import java.util.function.Consumer;

public class Who {

    private final String name;

    public Who(String name) {
        this.name = name;
    }

    private String name() {
        return name;
    }

    private void reName() {
        new Who("堀北真希") {
            Consumer c = name -> {
                printName(name);
            };

            private void printName(String name) {
                System.out.println("本名 " + name + " , 芸名 " + name());
            }
        }.c.accept(name);
    }

    public static void main(String[] args) {
        new Who("原麻里奈").reName();
    }
}

1.本名 原麻里奈 , 芸名 堀北真希

2.本名 原麻里奈 , 芸名 原麻里奈

3.コンパイルエラー

4.実行時エラー

 

解答は後日気が向けば書きます。(書くほどのもんじゃない(^_^;)

できれば面倒なので誰か種明かしをコメントとして書いてくれるとありがたいです。

Hatena タグ: