TIL| Java Java Stream
航海99の2週目のアルゴリズム週間で、与えられた問題を解きながら、他の人の解答を観察してみると、よく使われるものがいくつかあることに気づき、その一つJavaのStreamを学びたいと思っていました.
ストリーム(Stream)
作成-Streamインスタンスの作成 加工-Filter、Map、Sond、Peak(中間操作) 作成結果-端末操作
配列と集合に加えて、複数の方法でStreamを作成することもできます.
配列は、
Collection、List、Setなどの集合タイプでは、
配列/集合ではなくコンストラクタを使用して、Streamに直接値を入れることができます.
Supplier-パラメータがなく、戻り値のみの関数インタフェースです.
生成されたStreamオブジェクトを使用してStream内の要素を加工し、必要な要素のみを抽出できます.これらのプロセスは中間操作(intermediate operations)と呼ばれ、操作が完了するとStreamオブジェクトが返されるため、複数の加工操作を一度にリンクすることができます.
フィルタ(Filter)は、Streamオブジェクト内の各要素を評価し、必要な基準を満たす要素をフィルタします.
boolean値を返す関数型インタフェース
マッピング(Map)は、ストリームオブジェクトの要素を特定の値に変換するためのパラメータとしてラムダ式を受け入れます.
Streamオブジェクト内の要素をソートする方法.
他のソートと同様に、Comparatorの方法を使用します.
ラムダ式Consumerをパラメータとして受け入れるので、元素を加工しても返さない方法です.
以上では、Streamを加工して別のStreamオブジェクトに戻す中間操作(Intermediate Operation)、加工要素を出力したり、他のアレイ/セットに送信したりする最終操作(Terminal Operation)を行う必要があります.
以下の例があります.
Streamで作業した結果がリストに戻ります.
Streamで動作した結果をStringに接続します.
++
それ以外にも、以下の方法があります. Collectors.AVeragingInt()-数値を求める平均値 Collectors.和()-数値の和を求める Collectors.要約図()-数値を求める個数、和、平均値、最大値および最小値 Collectors.groupingBy()-特定の条件で要素をグループ化 Collectors.パーティションBy()-特定の条件で要素をグループ化(boolen値を返す) Collectors.collectingAndThen()-collectの後に他の操作を実行する必要があります Collectors.of()- アキュムレータ-Stream要素が来るたびに結果(関数積算) を生成identify-アキュムレータと同じ初期値を持つ(Streamが空の場合は初期値を返す) combiner-パラレルStreamの各Streamの計算結果をマージ
Streamの要素は
ストリーム(Stream)
Java StreamはJava 8からサポートされている機能で、集合に格納されている要素を迂回して処理できるコードモードです.ストリームの前に、for
、foe-each
文を使用して配列または集合インスタンスの要素を処理できますが、論理が複雑であればあるほどコードが長くなるか、ループが多くなります.
逆に、Streamは「データストリーム」であり、配列、集合で関数を組み合わせ、必要な値を加工またはフィルタリングし、Ramdaを使用してコードを簡潔に表現することができます.
理解する内容
作成
配列と集合に加えて、複数の方法でStreamを作成することもできます.
1.Streamの配列
配列は、
Arrays.stream()
メソッドパラメータに配列を入力することによって配列を巡回するStreamオブジェクトを作成することができる.String[] arr = new String[]{"a", "b", "c"};
Stream<String> stream1 = Arrays.stream(arr);
Stream<String> stream2 = Arrays.stream(arr, 1, 3); // idx 1포함 3 제외 [b, c]
2.コレクションStream
Collection、List、Setなどの集合タイプでは、
stream()
メソッドを使用してStreamオブジェクトを作成できます.List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
3. Stream builder
配列/集合ではなくコンストラクタを使用して、Streamに直接値を入れることができます.
add
に値を追加し、メソッドを使用してStreamを返すことができます.Stream<String> builderStream = Stream.<String>builder()
.add("Eric")
.add("Elena")
.add("Java")
.build(); // [Eric, Elena, Java]
4. Stream generate
build()
に相当するランダを使用してStreamを作成します.Supplier-パラメータがなく、戻り値のみの関数インタフェースです.
Supplier<T>
でreturn値が生成されます.public static<T> Stream<T> generate(Supplier<T> s) { ... }
Stream.generateは無限のStreamになるので、Streamを生成するにはサイズを制限する必要があります.Stream<String> stream = Stream.generate(() -> "hyemco").limit(3);
limit()を使用して、3つの「hyemco」を含むStreamを生成します.5.基本金Stream
Supplier<T>
を使用することもできますが、リストまたは配列を使用して基本タイプ(int、long、double)Streamを直接作成できます.IntStream stream = IntStream.range(1, 3) // [1, 2]
LongStream stream = LongStream.raneClosed(1, 3) // [1, 2, 3]
generate
とrange()
の範囲が異なり、後者は終了因子を含む範囲を生成する.++接続Stream
rangeClosed()
では、2つのStreamを接続して新しいStreamオブジェクトを作成できます.Stream<String> stream1 = Stream.of("one", "two", "three");
Stream<String> stream2 = Stream.of("하나", "둘", "셋");
Stream<String> concat = Stream.concat(stream1, stream2);
// [one, two, three, 하나, 둘, 셋]
加工
生成されたStreamオブジェクトを使用してStream内の要素を加工し、必要な要素のみを抽出できます.これらのプロセスは中間操作(intermediate operations)と呼ばれ、操作が完了するとStreamオブジェクトが返されるため、複数の加工操作を一度にリンクすることができます.
1. Filter
フィルタ(Filter)は、Streamオブジェクト内の各要素を評価し、必要な基準を満たす要素をフィルタします.
boolean値を返す関数型インタフェース
Stream.concat
を使用して、true値のみを返します.Stream<Integer> stream = IntStream.range(1, 10);
stream.filter(v -> (v % 2 == 0).forEach(System.out::prrintln);
// [2, 4, 6, 8]
1から9までのStreamを生成し,filter法に偶数をスクリーニングしたRam茶食を加え,1~9で偶数元素のみがstreamオブジェクトに戻る.2. Map
マッピング(Map)は、ストリームオブジェクトの要素を特定の値に変換するためのパラメータとしてラムダ式を受け入れます.
List<String> names = Arrays.asList("Eden", "Jin", "Harry");
Stream<String> stream = names.stream().map(String::toUpperCase);
// [ERIC, JIN, HARRY]
map()のようなPredicate
Methodもあり、これはパラメータ形式で受信されたラムダ式戻りタイプStreamである.通常、オーバーラップ構造Streamを「フラット化」(Flatting)と呼ばれる別個のStreamとして作成するために使用されます.List<List<String>> list =
Arrays.asList(Arrays.asList("a", "b", "c"),
Arrays.asList("가", "나", "다"));
// [[a, b, c], [가, 나, 다]]
上のネスト構造のリストは、flatMap()
でネスト構造を削除します.List<String> flatList = list.stream().flatMap(Collection::stream)
.collect(Collectiors.toList());
// [a, b, c, 가, 나, 다]
3. Sorted
Streamオブジェクト内の要素をソートする方法.
他のソートと同様に、Comparatorの方法を使用します.
Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);
1)パラメータなし呼び出し-昇順ソートIntStream.of(11, 7, 24, 2).sorted().boxed().collect(Collectors.toList());
// [2, 7, 11, 24]
2)ファクタの順序を超えた場合List<String> lang =
Arrays.asList("Java", "Scala", "Groovy", "Python", "Go", "Swift");
lang.stream()
.sorted()
.collect(Collectors.toList());
// [Go, Groovy, Java, Python, Scala, Swift]
// Comparator로 알파벳 역순으로 정렬
lang.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
// [Swift, Scala, Python, Java, Groovy, Go]
4. Peak
ラムダ式Consumerをパラメータとして受け入れるので、元素を加工しても返さない方法です.
Stream<T> peek(Consumer<? super T> action);
したがって,Stream内の演算では,中間過程の結果を調べるためによく用いられる.int sum = IntStream.of(1, 3, 5, 7, 9)
.peek(System.out::println)
.sum();
結果の作成
以上では、Streamを加工して別のStreamオブジェクトに戻す中間操作(Intermediate Operation)、加工要素を出力したり、他のアレイ/セットに送信したりする最終操作(Terminal Operation)を行う必要があります.
1. Collecting
flatMap
メソッドは、collect
オブジェクトによって提供されるCollector
タイプのパラメータを受け入れて処理する.以下の例があります.
List<Product> productList =
Arrays.asList(new Product(23, "potatoes"),
new Product(14, "orange"),
new Product(13, "lemon"),
Collectors.toList()
Streamで作業した結果がリストに戻ります.
List<String> list =
productList.stream()
.map(Product::getName)
.collect(Collectors.toList());
// [potatoes, orange, lemon]
Collectors.joining()
Streamで動作した結果をStringに接続します.
String listToString =
productList.stream()
.map(Product::getName)
.collect(Collectors.joining());
// potatoesorangelemon
String listToString =
productList.stream()
.map(Product::getName)
.collect(Collectors.joining(", ", "<", ">"));
// <potatoes, orange, lemon, bread, sugar>
Collectors
の最初のパラメータ(区切り記号)は要素区切り記号であり、2番目のパラメータ(prefix)は戻り値の一番前の文字であり、3番目のパラメータ(接尾辞)は最後の文字である.++
それ以外にも、以下の方法があります.
joining
カスタム2.数値の統計
collector
およびsum
は、Streamが空の場合に0を出力する.最高価格で、最高価格でオプションを利用して返却します.int sum = IntStream.of(2, 4, 6, 8, 10).sum();
int count = IntStream.of(2, 4, 6, 8, 10).count();
int average = IntStream.of(2, 4, 6, 8, 10).average();
OptionalInt min = IntStream.of(2, 4, 6, 8, 10).min();
OptionalInt max = IntStream.of(2, 4, 6, 8, 10).max();
3. Reduce
count
メソッドには3つのパラメータがあります.// 1개 (accumulator)
Optional<T> reduce(BinaryOperator<T> accumulator);
// 2개 (identity)
T reduce(T identity, BinaryOperator<T> accumulator);
// 3개 (combiner)
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
例// accumulator 예시
OptionalInt reduced = IntStream.range(1, 4) // [1, 2, 3]
.reduce((a, b) -> {
return Integer.sum(a, b);
});
// 6 (1부터 3까지 요소들을 더해줌 - 1+2+3)
// identify 예시
int reduced = IntStream.range(1, 4) // [1, 2, 3]
.reduce(10, Integer::sum);
// 16 (초기값 10에 1부터 3까지 요소들을 더해줌 - 10+1+2+3)
// combiner 예시
Integer reduced = Arrays.asList(1, 2, 3)
// 병렬 Stream
.parallelStream()
.reduce(10, Integer::sum, (a, b) -> {
System.out.println("combiner was called");
return a + b;
});
// combiner was called
// combiner was called
// 36
// (accumulator가 초기값 10에 각 Stream 값을 더한 11, 12, 13 세 개의 값을 구하고
//combiner가 여러 쓰레드에 나눠 계산한 결과를 합져준다 - 11+12=23, 23+13=36)
4. foreach
Streamの要素は
reduce
回りに回転して加工され、foreach
で結果を出力する際によく使用されます.List<Integer> evenNumber = IntStream.range(1, 10).boxed()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
// 2 / 4 / 6 / 8
Reference
この問題について(TIL| Java Java Stream), 我々は、より多くの情報をここで見つけました https://velog.io/@hyemco/TIL-Java-자바-Streamテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol