LoginSignup
1
3

More than 3 years have passed since last update.

【Java入門】Stream APIについて

Last updated at Posted at 2020-07-16

目的

Java言語を含めたプログラミングの学習を始めたばかりの方、既学習者の方は復習用に、
今回はStream APIについて学ぶために書いています。

【Java入門目次】
変数と型
型変換
変数のスコープ
文字列の操作
配列の操作
演算子
条件分岐
繰り返し処理
・クラスについて(準備中)
・抽象クラス(準備中)
・インターフェース(準備中)
・カプセル化(準備中)
・モジュールについて(準備中)
例外処理について
ラムダ式について
・Stream APIについて ←今ここ

Stream APIとは

Java8から導入された機能で、コレクションの要素に対する操作が可能なAPIです。

コレクションをStream化→中間操作(データを加工)→終端操作(加工したデータを得る)

という処理の流れになります。

Stream APIの中間操作は複数記述することが可能なので、複雑そうに見える処理もスッキリと記述することが出来ます。

各メソッドの引数に関数型インターフェースを受け取る場合もあり、そこでラムダ式を用いていますがそこの説明は割愛します。
ラムダ式についてをご覧ください。

Stream APIの例

実際にどの様に扱うのか簡単な例で比較します。

まずは、Stream APIを使わず実装。

List<String> names = Arrays.asList("大瀬良", "佐村河内", "菊池", "畝", "長野", "城之内");
for (int i = 0; i < names.size(); i++) {
  if (names.get(i).length() >= 3) {
    if (names.get(i).contains("内")) {
      System.out.println(names.get(i)); // 佐村河内 城之内
    }
  }
}

次に、Stream APIを使って同様の処理を実装します。

StreamAPIを使用した実装
List<String> names = Arrays.asList("大瀬良", "佐村河内", "菊池", "畝", "長野", "城之内");
names.stream()
     .filter(name -> name.length() >= 3)
     .filter(name -> name.contains("内"))
     .forEach(name -> System.out.println(name)); // 佐村河内 城之内

ネストが深くならず読みやすくなり、シンプルに実装出来ていますね。

中間操作のfilterメソッドで条件を満たす要素のみを抽出し、
終端操作のforEachメソッドで1つずつ要素を出力しています。

中間操作の紹介

先程は中間操作のメソッドとしてfilterを紹介しましたが、その他のメソッドもいくつか紹介していきます。

1.map

各要素に指定した処理を行うメソッドです。

mapメソッド
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream()
       .map(num -> num * 2) // 各要素を2倍にする
       .forEach(num -> System.out.print(num + " ")); // 2 4 6 8 10

2.limit

指定した要素数(maxSize個)だけを返してくれるメソッドです。

limitメソッド
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream()
       .limit(3) // 3個だけ取り出す
       .forEach(num -> System.out.print(num + " ")); // 1 2 3 

3.distinct

重複を除いた要素を返してくれるメソッドです。

distinctメソッド
List<String> names = Arrays.asList("久保", "遠藤", "巻", "久保", "岡崎", "本田", "巻", "遠藤");
names.stream()
     .distinct() // 重複した要素は取り除いて返す
     .forEach(name -> System.out.print(name + " ")); // 久保 遠藤 巻 岡崎 本田

4.sorted

要素を並び替えてくれるメソッドです。

sortedメソッド
List<Integer> numbers = Arrays.asList(1, 5, 3, 2, 4);
numbers.stream()
       .sorted() // 昇順に並び替え
       .forEach(num -> System.out.print(num + " ")); // 1 2 3 4 5

sortedメソッドの引数にComparatorインターフェースのreverseOrderメソッドを渡すことで、降順に並び替えることも出来ます。

sortedメソッド
List<Integer> numbers = Arrays.asList(1, 5, 3, 2, 4);
numbers.stream()
       .sorted(Comparator.reverseOrder()) // 降順に並び替え
       .forEach(num -> System.out.print(num + " ")); // 5 4 3 2 1

終端操作の紹介

これまでは終端操作のメソッドとしてforEachメソッドを用いていましたが、その他のメソッドもいくつか紹介していきます。

1.anyMatch

条件によってbooleanを返すメソッドです。
要素の中に1つでも条件に合致する値があればtrueを返します。(一部一致判定)

anyMatchメソッド
List<String> fruits = Arrays.asList("banana", "apple", "orange", "pineapple");
boolean result = fruits.stream()
                       .anyMatch(fruit -> fruit.length() >= 7); // 7文字以上の文字数の要素はあるか判定
System.out.println(result); // true

2.allMatch

条件によってbooleanを返すメソッドです。
要素全てが条件に合致していればtrueを返します。(全部一致合致)

allMatchメソッド
List<Integer> numbers = Arrays.asList(2, 4, 6, 7, 8, 10);
boolean result = numbers.stream()
                        .allMatch(num -> num % 2 == 0); // 要素全てが偶数であるかを判定している
System.out.println(result); // false

3.noneMatch

条件によってbooleanを返すメソッドです。
要素の中に1つでも条件に合致するもがあればfalseを返します。(全て非合致判定)

noneMatchメソッド
List<String> names = Arrays.asList("鈴木", "松井", "野茂", "井川", "川崎", "新庄", "ダルビッシュ有");
boolean result = names.stream()
                      .noneMatch(name -> name.length() > 4); // 4文字以上の文字数の要素はあるか判定
System.out.println(result); // false

終わりに

コレクション要素に対しての操作を自分でダラダラと書くより、Stream APIを用いる事でソースコードがシンプルで読みやすくなるという事が分かりました。
最初は戸惑うかもしれませんが、ラムダ式と一緒にしっかりと覚えておきたいですね。

参考サイト

Stream Oracle公式
【Java】Stream APIを書き続けて得た知見

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3