Java 8のStream API入門


Java 8のStream APIについての紹介です。Stream APIではラムダ式を使うのでラムダ式を合わせて説明します。


ラムダ式(Lambda)

Javaのラムダ式(Lambda)は、クロージャ(Closure)とも呼ばれています。ラムダ式は「関数型インターフェイス」の実装で使います。

@FunctionalInterface
public interface IntFunc {
public abstract void func(int x);
}

IntFunc intFunc1 = new IntFunc() {
@Override
public int func(int x) {
return x + x;
}
}

ラムダ式を使うと上のインターフェイスを次のように書き直すことができます。

IntFunc intFunc2 = (int x) -> { return x + x; };

Stream API

Java 8で導入された機能で、配列やCollectionなどの集合体の値の集計などに便利なAPIです。Streamといったインターフェイスで要素を処理します。

Stream APIには「中間操作」と「終端操作」が存在します。

中間操作を行う主なメソッドは次のようなものがあります。

😎 条件を満たす要素のみ選別:filter

filterメソッドは、Predicateで定義したbooleanの判定がtrueの要素のみに絞ったStreamを返します。

Integer[] array = { 1, 2, 3, 4, 5, 6, 7 };
Arrays.stream(array)
.filter(new Predicate() {
@Override
public boolean test(Integer val) {
return val % 3 == 0;
}
})
.forEach(System.out::println);
// 3
// 6

上記と同じことを省略形で書くと次のようになります。

Integer[] array = { 1, 2, 3, 4, 5, 6, 7 };
Arrays.stream(array)
.filter(val -> val % 3 == 0)
.forEach(System.out::println);
// 3
// 6

😸 各要素に特定の処理を行う:map

mapメソッドは、各要素に対して指定した処理を行いその結果のStreamを返します。

Integer[] array = { 1, 2, 3 };
Arrays.stream(array)
.map(new Function() {
@Override
public Integer apply(Integer val) {
return val * 3;
}
})
.forEach(System.out::println);

上記と同じことを省略形で書くと次のようになります。

Integer[] array = { 1, 2, 3 };
Arrays.stream(array)
.map(val -> val * 3)
.forEach(System.out::println);
// 3
// 6
// 9

🏀 指定した個数の要素を返す:limit

limitメソッドはmaxSize個の要素のStreamを返します。

Integer[] array = { 1, 2, 3, 4, 5, 6, 7 };
Arrays.stream(array)
.limit(3)
.forEach(System.out::println);
// 1
// 2
// 3

🐯 重複のない要素を返す:distinct

distinctメソッドはmaxSize個の要素のStreamを返します。

Integer[] array = { 1, 2, 1, 2, 1, 2 };
Arrays.stream(array)
.distinct()
.forEach(System.out::println);
// 1
// 2

🗻 指定した並び順に並べ直す:sorted

sortedメソッドは、Comparatorで比較し並べ替えたStreamを返します。

List list = Arrays.asList(3, 2, 1);
list.stream()
.sorted()
.forEach(System.out::println);
// 1
// 2
// 3

🐰 集合に対する操作:collect

collectメソッドはArrayやList等のデータ構造を変化するのに使います。

List list = Arrays.asList(3, 2, 1);
List result = list.stream()
.sorted()
.collect(Collectors.toList());

result.stream().forEach(System.out::println);

Collectorsで文字列の連結:joining

Collectorsのメソッドで文字列の連結に使うのがjoiningメソッドです。

System.out.println(Stream.of("A", "B", "C")
.collect(Collectors.joining("-"))); //=> A-B-C
System.out.println(Stream.of("A", "B", "C")
.collect(Collectors.joining("-", "[", "]"))); //=> [A-B-C]

🚌 ひとつでもマッチすればtrueを返す:anyMatch

anyMatchメソッドは要素の中でどれかひとつでも条件にマッチすればtrueを返します。

List list = Arrays.asList("Tokyo", "Osaka", "Nagoya");
System.out.println(list.stream().anyMatch(val -> val.length() == 6)); //=> true
System.out.println(list.stream().anyMatch(val -> val.length() == 7)); //=> false

😼 すべて一致すればtrueを返す:allMatch

allMatchメソッドはすべての要素が条件を満たせばtrueを返します。

List list = Arrays.asList("Tokyo", "Osaka", "Nagoya");
System.out.println(list.stream().allMatch(val -> val.length() >= 5)); //=> true
System.out.println(list.stream().allMatch(val -> val.length() >= 6)); //=> false

🍄 すべてマッチしなければtrueを返す:noneMatch

noneMatchメソッドはすべての要素が条件を満たさない、ひとつもマッチしない場合にtrueを返します

List list = Arrays.asList("Tokyo", "Osaka", "Nagoya");
System.out.println(list.stream().noneMatch(val -> val.length() >= 7)); //=> true
System.out.println(list.stream().noneMatch(val -> val.length() >= 6)); //=> false

🏈 参考リンク

🖥 VULTRおすすめ

VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。 最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!

📚 おすすめの書籍