Java基礎ーStream

StreamAPI

配列やCollectionなどの集合体を扱う為のもので、値の集計やデータを使った処理などが出来るAPI

使い方の大まかな流れ

1. Streamを取得

主なStreamの種類

インターフェイス 説明
Stream<t> 要素がTのインスタンスのStream
IntStream 要素がintの値のStream
LongStream 要素がlongの値のStream
DoubleStream 要素がdoubleの値のStream

Streamの作り方

①Streamから作る

// String型のStream
Stream<String> ss = Stream.of("One", "Two", "Three", "Four");

// 1から10の値を発生させるint型のStream
IntStream is = IntStream.rangeClosed(1, 10);

②Collection型から作る

// Listから生成
List<String> strList = Arrays.asList("A", "B", "C", "D");
Stream<String> ss = strList.stream();

// Mapから生成
Map<String, Integer> map = new HashMap<>();
// (Key,Value)の組でStreamを作る
Stream<Map.Entry<String, Integer>> map.entrySet().stream();

2. 中間操作…0回以上複数回できる

◇ できること
・Streamインスタンスの各要素を条件で絞った新たなStreamインスタンスの取得
・Streamインスタンスの各要素から別のデータを要素として持つStreamインスタンスを生成

◇ 中間操作の主なメソッド

メソッド 説明
filter(Predicate predicate) Predicateで定義したbooleanの判定がtrueの要素のみに絞ったStreamを返す
map(Function<T, R>) 要素に処理を加える。別の型に変換することもできる
limit(long i) 要素の最初からiまでの要素のStreamを返す
skip(long i) 要素の最初からiまでの要素をスキップしたStreamを返す
distinct() 要素同士を比較し重複するものを除いたStreamを返す
sorted(Comparator<T>) 要素のソートを行う
takeWhile(Predicate predicate) 条件を満たしている間だけ処理を行う。一度満たさなくなると以降の処理は行わない
dropWhile(Predicate predicate) 条件を満たしている間は処理が行われない。一度条件を満たさなくなると、以降は処理を実行する
T ofNullable(T t) 引数に指定する値がnullでない場合はStreamを返し、nullの場合は空のStreamを返す

◇ メソッド使用例

Integer[] array = { 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6 };

// filterメソッド
Stream<Integer> stream1 = Arrays.stream(array);
Stream<Integer> filterStream = stream1.filter(value -> value % 3 == 0);
filterStream.forEach(value -> System.out.println("filterStream: " + value)); // 3 6 3 6

// mapメソッド
Stream<Integer> stream2 = Arrays.stream(array);
Stream<Integer> mapStream = stream2.map((i) -> i + 5);
mapStream.forEach(value -> System.out.println("mapStream: " + value)); // 6 7 8 9 10 11 12 6 7 8 9 10 11

// limitメソッド
Stream<Integer> stream3 = Arrays.stream(array);
Stream<Integer> limitStream = stream3.limit(3);
limitStream.forEach(value -> System.out.println("limitStream: " + value)); // 1 2 3

// skipメソッド
Stream<Integer> stream4 = Arrays.stream(array);
Stream<Integer> skipStream = stream4.skip(3);
skipStream.forEach(value -> System.out.println("skipStream: " + value)); // 4 5 6 7 1 2 3 4 5 6

//distinctメソッド
Stream<Integer> stream5 = Arrays.stream(array);
Stream<Integer> distinctStream = stream5.distinct();
distinctStream.forEach(value -> System.out.println("distinctStream: " + value)); //1 2 3 4 5 6 7

//sortメソッド
Stream<Integer> stream6 = Arrays.stream(array);
Stream<Integer> sortStream = stream6.sorted((x, y) -> x - y);
sortStream.forEach(value -> System.out.println("sortStream: " + value)); // 1 1 2 2 3 3 4 4 5 5 6 6 7

List<String> list = Arrays.asList("c", "h", "o", "c", "o", "l", "a", "t", "e");

Map<String, String> map =  Map.of("c", "C", "h", "H", "o", "O");
String st = "l";

// takeWhileメソッド
list.stream().takeWhile(x -> x != st).forEach(System.out.println(x)); // c h o c o

// dropWhileメソッド
list.stream().dropWhile(x -> x != st).forEach(System.out.println(x)); // l a t e

// ofNullableメソッド    
list.stream().flatMap(x -> Stream.ofNullable(map.get(x))).forEach(System.out::println); // C H O C O

3. 終端操作…1回のみ

◇ できること
・Streamインスタンスの要素から何らかの結果を取得したり要素を使って処理を行ったりする

◇ 終端操作の主なメソッド

メソッド 説明
void close() Streamを閉じる
void forEach(Consumer action) 各要素に対してactionを実行する
Object[] toArray() 配列化する
long count() 素数を返す
boolean anyMatch(Predicate p) p(e)の評価結果が1つでもtrueになる場合にtrueを返す
boolean allMatch(Predicate p) p(e)の評価結果がすべてtrueになる場合にtrueを返す
boolean noneMatch(Predicate p) p(e)の評価結果がすべてfalseになる場合にtrueを返す

◇ メソッド使用例

// closeメソッド
Stream<Integer> stream1 = Arrays.stream(array);
Stream<Integer> closeStream = stream1.filter(value -> value % 3 == 0);
closeStream.close();

// forEachメソッド
Stream<Integer> stream2 = Arrays.stream(array);
Stream<Integer> forEachStream = stream2.filter(value -> value % 3 == 0);
forEachStream.forEach(value -> System.out.println("forEachStream: " + value)); // 3 6 3 6

// toArrayメソッド
Stream<Integer> stream3 = Arrays.stream(array);
Stream<Integer> toArrayStream = stream3.filter(value -> value % 3 == 0);
Object[] array2 = toArrayStream.toArray();

// countメソッド
Stream<Integer> stream4 = Arrays.stream(array);
Stream<Integer> countStream = stream4.filter(value -> value % 3 == 0);
long count = countStream.count(); // count = 4

// anyMatchメソッド
Stream<Integer> stream5 = Arrays.stream(array);
Stream<Integer> anyMatchStream = stream5.filter(value -> value % 3 == 0);
boolean anyMatch = anyMatchStream.anyMatch(value -> value == 3); // anyMatch = true

// allMatchメソッド
Stream<Integer> stream6 = Arrays.stream(array);
Stream<Integer> allMatchStream = stream6.filter(value -> value % 3 == 0);
boolean allMatch = allMatchStream.allMatch(value -> value == 3); // allMatch = true

// noneMatchメソッド
Stream<Integer> stream7 = Arrays.stream(array);
Stream<Integer> noneMatchStreamm = stream7.filter(value -> value % 3 == 0);
boolean noneMatch = noneMatchStreamm.noneMatch(value -> value == 3); // noneMatch = true