mike、mikeなるままに…

プログラムに関してぬるま湯のような記事を書きます

Rubyのmixinの話を読んでいたら、何故かjavaを書いていた

こんにちわ、みけです。

@suginoyさんに

『楽しい開発スタートアップRuby』を買っていただいたので、

今日はそれを某社オフィスで読んでいました。

Rubyのmix-inについての読んだ後の会話

  • 僕「mix-inよくわからん」
  • イケメン「多重継承できるやつでしょう」
  • 僕「mix-inってインスタンス変数とかにアクセスできるのかな?」
  • イケメン「できそうじゃね」
  • 僕「あ〜、Java8のdefault実装でもmix-inと同じ事できそうじゃね」
  • イケメン「いや、できないでしょう。default実装といっても、interfaceにフィールドを持つことができないわけだから」
  • 僕「え、できないのか、あー、そうかできないな。えっ、じゃあ、あれ、誰得なの?」

(多少脚色有り、あと会話内容忘れたので、結構適当)

で、

書いていたのがJava8のコードでした

Score.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
package org.mikeneck.jdk8;

/**
 * @author mike
 */
public class Score {

    final private String title;

    final private int value;

    public Score(String title, int value) {
        this.title = title;
        this.value = value;
    }

    public String getTitle() {
        return title;
    }

    public int getValue() {
        return value;
    }
}
Grade.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package org.mikeneck.jdk8;

import java.util.List;

/**
 * @author mike
 */
public interface Grade {

    public List<Score> scores();

    default long getTotalScore () {
        return scores()
                .stream()
                .mapToLong(Score::getValue)
                .reduce(0l, Long::sum);
    }
}

ところで、このdefaultメソッド、

書いている途中はこんな感じでした。

IntelliJ IDEAではシンタックスをもっとよくできる場合は、

こういう形で通知してくれます。

紫の部分にカーソルをあてて、

Alt + Enter (mac の場合は option + enter)をすると、

操作の候補が表示されます。

ここではReplace lambda with method referenceを選択します。

すごいシンプルなコードになりました。

続いて、mapした結果をreduceしていきます。

初期値0lで、結果を合計したいので、次のような演算を書きます。

これはこれでまちがいでありません。

ところで、java.util.stream.Stream#mapToLongの戻り値である、

java.util.stream.LongStreamのjavadocを読むとこのように記述されています。

Api note : Sum, min, max, and average are all special cases of reduction. Summing a stream of numbers can be expressed as:

long sum = integers.reduce(0, (a, b) -> a+b);

or more compactly:

long sum = integers.reduce(0, Long::sum);

引用元 : javadoc (build-89)

つまり、java.util.function.LongBinaryOperatorの記述

1
(sum, item) -> sum + item

は、java.lang.Longstaticなメソッドsum(long, long)

置き換えることができるということです。

その結果、先のコードは次のようになりました(既出)。

さて、ここらへんのStream系の操作がエンタープライズな現場で使われるかどうかは

微妙ですが…(というのも、値の集計をするというのであれば、DBにさせたほうが早いので)

実際に現場で使うとなると、

高機能なIDE(Long::sumの部分はIntelliJでも簡略化できなかった)と

Stream系のApiの書き方を覚えておかないと、

相当効率悪くなるとおもいます。

というわけで、Java8の勉強をしたい方は是非

6月26日(水)の『Java8初心者勉強会』にご参加下さい。

Java8初心者勉強会 – http://atnd.org/event/java8beginner20130626tokyo

結論

あれ、rubyのmix-inについての話はどこ行った…

vimでrubyのコード書くの辛いです…