streamの終端処理いろいろ。

Java
スポンサーリンク

Java8以降使用可能となったstreamの終端処理についてです。いろいろな処理ができるため、備忘を兼ねてまとめました。使用方法の例をつけています。

終端処理 説明
findFirst()

ストリームの最初の要素を返します。
リストの中に該当データが1つしかない場合によく使用します。戻り値は、Optional<T>ですが、orElse()等合わせて使用することが多いです。
SchoolDto schoolDto = schoolDtoList.stream()
.filter(f -> Objects.equals(f.getCode(), "9999"))
.findFirst() .orElse(null);
findAny()

ストリームの中から条件に該当するデータのどれか一つを返します。
リストの中に複数該当するデータがある場合、どれか一つを返します。戻り値は、Optional<T>ですが、orElse()等合わせて使用することが多いです。
先頭データを常に取得したい場合は、findFirst()を使用します。

SchoolDto schoolDto = schoolDtoList.stream()
.filter(f -> f.getName().contains("小学校"))
.findAny() .orElse(null);
collect(Collectors.toList())
 
collectは可変リダクション操作を実行します。
と公式サイトでは紹介されています。Collectors.toList()を指定するとリストでstreamの結果を取得します。他にもSetで取得したりできます。
List<SchoolDto> schoolDto = schoolDtoList.stream()
.filter(f -> f.getName().contains("小学校"))
.collect(Collectors.toList());
sum()

mapToInt()で取得した数値を合計したい場合等に使用します。
mapToLong、mapToDoubleも使用可能です。

Integer studentCount = schoolDtoList.stream()
.mapToInt(m -> m.getStudentCount()).sum();
distinct()

リストから、一部のデータを抜き出して、重複を排除したいとき等に使用します。

List<Integer> foundedYears = schoolDtoList.stream()
.map(SchoolDto::getFoundedYear).distinct()
.collect(Collectors.toList());
toArray()

結果を配列で取得します。
Integer[] foundedYears = schoolDtoList.stream()
.map(SchoolDto::getFoundedYear).distinct()
.toArray(Integer[]::new);
min(comparator)
 
最小の要素を取得します。戻り値はOptional<T>です。
Integer foundedYears = schoolDtoList.stream()
.map(SchoolDto::getFoundedYear)
.min(Comparator.naturalOrder()) .orElse(null);

// Dtoの1項目(ここではfoundedYear)が最小データを取得
SchoolDto schoolDto = schoolDtoList.stream()
.min(Comparator.comparing(SchoolDto::getFoundedYear))
.orElse(null);
max(comparator)
 
最大の要素を取得します。戻り値はOptional<T>です。
Integer foundedYears = schoolDtoList.stream()
.map(SchoolDto::getFoundedYear)
.max(Comparator.naturalOrder())
.orElse(null);

SchoolDto schoolDto = schoolDtoList.stream()
.max(Comparator.comparing(SchoolDto::getFoundedYear))
.orElse(null);
count()
 
ストリームの要素の個数を取得します。filterした結果が何件かを取得したいとき等使用します。
Long count = schoolDtoList.stream().count();
anyMatch
 
ストリーム内のある要素と一致するかを判断する際に使用します。
// どれか1つが該当していれば、trueとなります。
boolean result = schoolDtoList.stream()
.anyMatch(schoolDto -> Objects.equals(schoolDto.getCode(), "9999"));
allMatch
 
ストリーム内のすべての要素が一致するかを判断する際に使用します。
テストを書くときに使うことが多いです。
// すべての要素が一致しない場合、結果はfalseになります。
boolean result = schoolDtoList.stream()
.allMatch(schoolDto -> Objects.equals(schoolDto.getCode(), "9999"));
noneMatch
 
ストリーム内にすべての要素が一致しないかを判断する際に使用します。
// どの要素も一致しない場合、結果はtrueになります。
boolean result = schoolDtoList.stream()
.noneMatch(schoolDto -> Objects.equals(schoolDto.getCode(), "9999"));

以下は、少し応用編です。
List<T>をMapに変換します。

// 以下は、創立年ごとに学校をまとめたMapを作成しています。
Map<Integer, List<SchoolDto>> schoolDtoMap = schoolDtoList.stream()
.collect(Collectors.groupingBy(SchoolDto::getFoundedYear));

終端処理ではないですが、以下もよく使用します。

// sortedメソッドでlistをソートしています。
List<SchoolDto> schoolDto = schoolDtoList.stream()
.sorted(Comparator.comparing(SchoolDto::getFoundedYear))
.collect(Collectors.toList());

最後にflatMapの例を。
例えば、List<SchoolDto>があり、SchoolDtoのプロパティとして、List<StudentDto>を保持していたとします。これをflatMapでList<StudentDto>に簡単にまとめることができます。

List<SchoolDto.StudentDto> studentDtoList = schoolDtoList.stream()
.flatMap(schoolDto -> schoolDto.getStudentDtoList().stream())
.collect(Collectors.toList());

以上、streamの終端処理についてでした。他にも色々組み合わせて便利に使用できます。java8以降の開発ではぜひ使用してみてください。

参考URL

Stream (Java Platform SE 8)

コメント