いまさらJava8新機能について調べた

業務でメインで扱っているJavaのバージョンは7ですが、すでにEOL(サポートは2015年まで)です。
扱うパッケージソフトに依存しているため簡単には変更できませんが前職の職場ではようやくJavaのバージョンが8に変わる予定です。

自分自身も転職先ではJava8を利用すると思うので新機能を調査・整理しました。


関数型インターフェース

関数型インターフェイスとは、インターフェイスクラスにおいて1つの抽象メソッドを定義することを指します。
例えば以下のようなクラス構成が関数型インターフェイスになります。
アノテーションを明記して関数型インターフェイスとすることもできます。※あってもなくてもよい。

@FunctionalInterface
public interface GreetingInterface {
    public abstract String sayHello(String name);
}

ラムダ式

ラムダ式の特長は、メソッドを変数のように扱える点です。

書式は以下の通りで

■書式
(メソッドの引数列) -> {処理内容}

■ラムダ書式
(int x, int y) -> {return x + y;};

プログラムの形式で表現すると以下の通りです。

// 基本の書き方: (引数) -> { (処理) }
(int x, int y) -> {return x + y;};

// 引数の型は省略可能
(x, y) -> {
    return x + y;
};

// さらに1行処理の場合は{}とreturnも省略可能
(x, y) -> x + y;

// 引数が一つの場合は()が省略可能
name -> "Hello " + name;

ラムダ式単体では必須ではないですが、StreamAPIではラムダ式を前提としているため覚えておいたほうが良い知識です。
またラムダ式は関数型インターフェイスを簡潔に利用するための記法でもあります。

Stream API

配列やCollectionなどを集合体を扱える機能で、
たとえばプリミティブ型のクラスに対して以下のインターフェイスが追加されています。

インタフェース 概要

  • Stream    要素がTのインスタンスのStream
  • IntStream    要素がintの値のStream
  • LongStream   要素がlongの値のStream
  • DoubleStream 要素がdoubleの値のStream

他簡単な言い方として拡張For分を簡略化可能であるという点です。
Streamクラスに対して、filterメソッドで除外、mapメソッドで結合、foreachで繰り返し処理などが一行で実施できます。

Final省略

Java8ではラムダ式を利用するにあたって、扱う変数がFinal(固定化された値)である必要がありますが
実質FinalであればFinal宣言を省略可能です。
ただし、以下のように変数の処理を追加してしまうとコンパイルエラーの原因となります。

int cnt = 0; //final省略可
strs.forEach(str -> {
    System.out.println(str + cnt);   // 参照なのでOK
    cnt++;   // 代入はコンパイルエラー
});

メソッド参照

クラス・メソッドを
PHPのLaravelでも同じような書式で静的クラスの参照が行えました。

■書式
クラス名(インスタンス)::メソッド名

■メソッド参照

list.forEach(System.out :: println);

ラムダ式

list.forEach(x -> System.out.println(x));

日付時刻API

Dateクラスに該当するクラス、APIなどが色々増えている。

■追加クラス

  • LocalDateTime

タイムゾーンなし

  • ZonedDateTime

タイムゾーンあり

  • OffsetDateTime

タイムゾーンあり + offsetあり

他日時操作系メソッドは色々増えている。