社会人のメモ帳

忘れたくないことアレコレ

【第4週】第4章:終端操作のメソッドを実装してみる【Java Gold合格へ向けて】

PREV | LIST | NEXT

終端操作とは

中間操作を終えた要素の集合に対して行う最終の処理のことを指し、下記のようなメソッドが用意されている。今回はInteger型のListをStreamにし、終端操作を実施して結果値を確認する。

メソッド名 概要
allMatch ストリーム内のすべての要素が条件に一致するかどうかを調べる
anyMatch ストリーム内のいずれかの要素が条件に一致するかどうかを調べる
collect ストリームの要素を持つコレクションを戻す
count ストリーム内の要素を数える
findAny ストリーム内に要素が残っているかどうかの結果を持つOptionalを戻す
findFirst ストリーム内の最初の要素を持ったOptionalを戻す
forEach ストリーム内の要素を使って繰り返し処理を実行する
max ストリーム内の最大の要素を戻す
min ストリーム内の最小の要素を戻す
noneMatch ストリーム内の要素で条件に一致するものがないかどうかを調べる
reduce ストリーム内の要素を累積的に結合していくリダクション処理を実行する
toArray ストリームの要素を含む配列を戻す

中間操作を実装してみる

確認には「3, 2, 1, 1, 2, 3, 4」のInteger型のリストをstreamにしたもの対して行う。

allMatch

「3, 2, 1, 1, 2, 3, 4」の全ての値に対し「4より小さいか」を判定した結果として、「false」(4以上の値である4があるため)が出力されることが期待される。

public class Main {
    public static void main(String[] args) {
        List<Integer> inputList = List.of(3,2,1,1,2,3,4);
        Stream<Integer> inputStream = inputList.stream();
        Main.allMatch(inputStream);
    }

    public static void allMatch(Stream<Integer> stream){
        /* allMatch */
        System.out.println("=== allMatch ===");
        System.out.println("4以上の値が含まれない:"+stream.allMatch(i -> i < 4));
    }
}

実行結果

=== allMatch ===

4以上の値が含まれない:false

anyMatch

「3, 2, 1, 1, 2, 3, 4」の一つでも「4以上」の条件を満たす値があるか判定した結果として、「true」(4以上の値である4があるため)が出力されることが期待される。

public class Main {
    public static void main(String[] args) {
        List<Integer> inputList = List.of(3,2,1,1,2,3,4);
        Stream<Integer> inputStream = inputList.stream();
        Main.anyMatch(inputStream);
    }

    public static void anyMatch(Stream<Integer> stream){
        /* anyMatch */
        System.out.println("=== anyMatch ===");
        System.out.println("4以上の値が含まれる:"+stream.anyMatch(i -> i >= 4));
    }
}

実行結果

=== anyMatch ===

4以上の値が含まれる:true

collect

「3, 2, 1, 1, 2, 3, 4」のストリームをList型に変換して返すため、期待値としてはそのまま「3, 2, 1, 1, 2, 3, 4」が返ってくることが期待される。

public class Main {
    public static void main(String[] args) {
        List<Integer> inputList = List.of(3,2,1,1,2,3,4);
        Stream<Integer> inputStream = inputList.stream();
        Main.collect(inputStream);
    }

    public static void collect(Stream<Integer> stream){
        /* collect */
        System.out.println("=== collect ===");
        System.out.println(stream.collect(Collectors.toList()));
    }
}

実行結果

=== collect ===

[3, 2, 1, 1, 2, 3, 4]

count

「3, 2, 1, 1, 2, 3, 4」の要素数が返ってくるため、「7」が返ってくることが期待される。

public class Main {
    public static void main(String[] args) {
        List<Integer> inputList = List.of(3,2,1,1,2,3,4);
        Stream<Integer> inputStream = inputList.stream();
        Main.count(inputStream);
    }

    public static void count(Stream<Integer> stream){
        /* count */
        System.out.println("=== count ===");
        System.out.println(stream.count());
    }
}

実行結果

=== count ===

7

findAny

「3, 2, 1, 1, 2, 3, 4」の先頭の値が返ってくるため、「3」が返ってくることが期待される。 ※どうやらfilterなどと組み合わせることが普通の使い方であるらしい。

public class Main {
    public static void main(String[] args) {
        List<Integer> inputList = List.of(3,2,1,1,2,3,4);
        Stream<Integer> inputStream = inputList.stream();
        Main.count(inputStream);
    }

    public static void findAny(Stream<Integer> stream){
        /* findAny */
        System.out.println("=== findAny ===");
        Optional<Integer> list = stream.findAny();
        System.out.println(list.isPresent()? list.get() :"中身なし");
    }
}

実行結果

=== findAny ===

3

findFirst

「3, 2, 1, 1, 2, 3, 4」の先頭の値が返ってくるため、「3」が返ってくることが期待される。 ※どうやらfilterなどと組み合わせることが普通の使い方であるらしい。

public class Main {
    public static void main(String[] args) {
        List<Integer> inputList = List.of(3,2,1,1,2,3,4);
        Stream<Integer> inputStream = inputList.stream();
        Main.findFirst(inputStream);
    }

    public static void findFirst(Stream<Integer> stream){
        /* findFirst */
        System.out.println("=== findFirst ===");
        Optional<Integer> list = stream.findFirst();
        System.out.println(list.isPresent()? list.get() :"中身なし");
    }
}

実行結果

=== findFirst ===

3

forEach

「3, 2, 1, 1, 2, 3, 4」の値を一つずつ取り出しディスプレイに表示するため、「3, 2, 1, 1, 2, 3, 4」がそれぞれ表示されることが期待される。

public class Main {
    public static void main(String[] args) {
        List<Integer> inputList = List.of(3,2,1,1,2,3,4);
        Stream<Integer> inputStream = inputList.stream();
        Main.forEach(inputStream);
    }

    public static void forEach(Stream<Integer> stream){
        /* forEach */
        System.out.println("=== forEach ===");
        stream.forEach(i -> System.out.println(i));
    }
}

実行結果

=== forEach ===

3

2

1

1

2

3

4

max

「3, 2, 1, 1, 2, 3, 4」のリストの最大値を返すため、「4」が返ってくることが期待される。

public class Main {
    public static void main(String[] args) {
        List<Integer> inputList = List.of(3,2,1,1,2,3,4);
        Stream<Integer> inputStream = inputList.stream();
        Main.max(inputStream);
    }

    public static void max(Stream<Integer> stream){
        /* max */
        System.out.println("=== max ===");
        Optional<Integer> list = stream.max(Comparator.naturalOrder());
        System.out.println("最大値:" + (list.isPresent()? list.get() :"中身なし"));
    }
}

実行結果

=== max ===

最大値:4

min

「3, 2, 1, 1, 2, 3, 4」のリストの最小値を返すため、「1」が返ってくることが期待される。

public class Main {
    public static void main(String[] args) {
        List<Integer> inputList = List.of(3,2,1,1,2,3,4);
        Stream<Integer> inputStream = inputList.stream();
        Main.min(inputStream);
    }

    public static void min(Stream<Integer> stream){
        /* min */
        System.out.println("=== min ===");
        Optional<Integer> list = stream.min(Comparator.naturalOrder());
        System.out.println("最小値:" + (list.isPresent()? list.get() :"中身なし"));
    }
}

実行結果

=== min ===

最小値:1

noneMatch

「3, 2, 1, 1, 2, 3, 4」の一つでも「4以上の条件を満たす値が存在しない」ことを判定した結果として、「true」(4以上の値である4があるため)が出力されることが期待される。

public class Main {
    public static void main(String[] args) {
        List<Integer> inputList = List.of(3,2,1,1,2,3,4);
        Stream<Integer> inputStream = inputList.stream();
        Main.noneMatch(inputStream);
    }

    public static void noneMatch(Stream<Integer> stream){
        /* noneMatch */
        System.out.println("=== noneMatch ===");
        System.out.println("4以上の値が含まれない:"+stream.noneMatch(i -> i >= 4));
    }
}

実行結果

=== noneMatch ===

4以上の値が含まれない:false

reduce

「3, 2, 1, 1, 2, 3, 4」の値の合計値を返すため、「16」が出力されることが期待される。

public class Main {
    public static void main(String[] args) {
        List<Integer> inputList = List.of(3,2,1,1,2,3,4);
        Stream<Integer> inputStream = inputList.stream();
        Main.reduce(inputStream);
    }

    public static void reduce(Stream<Integer> stream){
        /* reduce */
        System.out.println("=== reduce ===");
        Optional<Integer> list = stream.reduce((i1,i2) -> i1+i2);
        System.out.println("合計値:" + (list.isPresent()? list.get() :"中身なし"));
    }
}

実行結果

=== reduce ===

合計値:16

toArray

「3, 2, 1, 1, 2, 3, 4」のStreamをInt型のリストに変換すると、出力されたリストを表示すると「3, 2, 1, 1, 2, 3, 4」がそのまま表示されることが期待される。

public class Main {
    public static void main(String[] args) {
        List<Integer> inputList = List.of(3,2,1,1,2,3,4);
        Stream<Integer> inputStream = inputList.stream();
        Main.reduce(inputStream);
    }

    public static void toArray(Stream<Integer> stream){
        /* toArray */
        System.out.println("=== toArray ===");
        Integer[] intList = stream.toArray(Integer[]::new);
        for(Integer i:intList) {
            System.out.println(i);
        }
    }
}

実行結果

=== toArray ===

3

2

1

1

2

3

4

まとめ

終端操作に関して実装して動かしてみたが、実際の使い方などについてより深く検証する必要があるように感じた。とりあえず今日は動かしてみるだけに止めているが、それでは理解したには程遠い。具体的に理解が必要なのは下記のような点が挙げられる。

  • collectは実際にどのような場合に使うのか
  • reduceは実際にどのような場合に使うのか
  • toArrayは実際にどのような場合に使うのか
  • findAnyとfindFirstの違い

上記は中間操作と組み合わせて使ったりすることで理解が深まるのではないかと思う。次の記事ではその辺りを実際に動かしていきたい。