JavaRush /Java Blog /Random-JA /ストリームAPI
Константин
レベル 36

ストリームAPI

Random-JA グループに公開済み
ストリームAPI - 1

ストリームAPIとは何ですか?

Stream API は、関数型スタイルでデータ構造を操作する新しい方法です。ストリーム API (あるコンピューター プログラムが別のプログラムと通信する方法の記述) は、本質的にはデータのストリームです。「スレッド」という用語自体は、プログラミング全般、特に Java においては非常に曖昧です。
ストリームAPI - 1
Java 8 の出現により、Stream API を使用すると、プログラマーは以前は多くのコード行を必要としていたものをより簡潔に記述できるようになり、データ セットの操作、特にフィルタリング、並べ替え、その他のデータ操作操作を簡素化できるようになりました。中間操作がない場合は、ストリームなしで行うことができ、多くの場合そうすべきです。そうしないと、コードはストリームなしよりも複雑になります。
ストリームAPI - 2
正確にはどこから始めればよいでしょうか? 必要なコレクション、配列、またはメソッドに基づいた Stream インスタンスの作成から、データの取得元は次のようになります。
List<String> list = new ArrayList<String>();
       list.add("One");
       list.add("Two");
       list.add("Three");
       list.add("Four");
       list.add("Five");
       list.add("Six");
       list.add("Seven");
       list.add("Eight");
       list.add("Nine");
       list.add("Ten");
       Stream stream = list.stream();
前述したように、Stream API を使用すると、コードの行数を減らすことができます。ストリームの例:
IntStream.of(50, 60, 70, 80, 90, 100, 110, 120).filter(x -> x < 90).map(x -> x + 10)
.limit(3).forEach(System.out::print);
スレッドなしの例:
int[] arr = {50, 60, 70, 80, 90, 100, 110, 120
	int count = 0;
	for (int x : arr) {
	    if (x >= 90) continue;
	    x += 10;
	    count++;
	    if (count > 3) break;
	    System.out.print(x);
	}
ストリームを作成する可能な方法:
ストリームAPI - 3
  • 空のストリーム:Stream.empty()
  • リストからストリーム:list.stream()
  • 地図からのストリーム:map.entrySet().stream()
  • 配列からのストリーム:Arrays.stream(array)
  • 指定された要素からストリーミングします。Stream.of("1", "2", "3")
さらに、演算子 (本質的には Stream クラスのメソッド) というものがあり、演算子は 2 つのグループに分類できます。
  • 中間(「遅延」とも呼ばれます) - 受信要素を処理し、ストリームを返します。要素処理チェーンには多くの中間演算子が存在する可能性があります。
  • ターミナル(「ターミナル」、「eager」とも呼ばれます) - 要素を処理してストリームを終了するため、チェーン内に存在できるターミナル オペレーターは 1 つだけです。
例:
1.List<String> list = new ArrayList<String>();
2.list.add("One");11.list.add("Ten");
12.Stream stream = list.stream();
13.stream.filter(x-> x.toString().length() == 3).forEach(System.out::println);
何が起きてる:
  • 1 - リストを作成しますlist
  • 2-11 - テストデータを入力します。
  • 12 - オブジェクトを作成しますStream
  • 13 - メソッドfilter(フィルター) - 中間演算子。x列挙のコレクションの 1 つの要素と同等です ( と同様for each)。その後 -> コレクションがどのようにフィルターされるかを示します。これは中間演算子であるため、フィルターされたコレクションはさらにメソッド。forEachこれは列挙の最終 (最終) 類似物ですfor each(式はSystem.out::println: の略でx-> System.out.println(x))、渡されたコレクションのすべての要素を調べて表示します)。
ストリームAPI - 5
重要な点:
  • 端末オペレーターが呼び出されるまで、処理は開始されません。list.stream().filter(s -> s > 5)(リストから要素を 1 つも取りません);
  • ストリームのインスタンスは複数回使用できません =( ;
  • ストリームAPI - 6

    したがって、新しいものがあるたびに、次のようになります。

    list.stream().filter(x-> x.toString().length() == 3).forEach(System.out::println);
    list.stream().forEach(x -> System.out.println(x));
  • 1 つのストリームでは多数の中間演算子を呼び出すことができますが、終端演算子は 1 つだけです。

    stream.filter(x-> x.toString().length() == 3).map(x -> x + " - the length of the letters is three").forEach(x -> System.out.println(x));
次に、いくつかの中間演算子を見てみましょう。
ストリームAPI - 7
  • filter(Predicate predicate)ストリームをフィルタリングし、条件に合格する要素のみを渡します (Predicate は、Java SE 8 でパッケージに追加された組み込み関数インターフェースです。 「 true」と「falsejava.util.function 」の値をチェックします)。
  • map(Function mapper)これにより、各要素を変更してさらにスキップする関数を作成できます (関数インターフェイスは、Function<T,R>タイプ T のオブジェクトからタイプ R のオブジェクトへの遷移関数を表します)
  • flatMap(Function<T, Stream<R>> mapper)- の場合と同様map、プリミティブ ストリームに変換するために使用されます。
たとえば、ストリームの配列 (配列、リストなど) を操作する場合、それらは 1 つのストリーム (配列、リストなど) に変換されます [stream1,stream2,stream3,stream4] => stream
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Convert the word to an array of letters
        .flatMap(Arrays::stream).distinct() //aligns each generated thread into a single thread
        .collect(Collectors.toList()).forEach(System.out::println);
スレッド (より正確にはスレッド)mapのリストに変換し ます。 <Stream>[stream1,stream2,stream3,stream4] =>Stream.of(stream1,stream2,stream3,stream4)
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Convert the word to an array of letters
        .map(Arrays::stream).distinct() //Make the array into a separate thread
        .collect(Collectors.toList()).forEach(System.out::println);
とのもう 1 つの違いはmap、1 つの要素をゼロ、1 つまたはその他の要素に変換できることです。1 つの要素を 0 の要素に変換するには、null、または空のストリームを返す必要があります。1 つの要素に変換するには、たとえば を介して 1 つの要素からストリームを返す必要がありますStream.of(x)。複数の要素を返すには、何らかの方法でこれらの要素を含むストリームを作成できます。同じ flatMap メソッドですが、Double、Integer、Long の場合:
  • flatMapToDouble(関数マッパー)
  • flatMapToInt(関数マッパー)
  • flatMapToLong(関数マッパー)
もう 1 つの比較例として flatMap を示します。
Stream.of(2, 3, 0, 1, 3)
        .flatMapToInt(x -> IntStream.range(0, x))
        .forEach(System.out::print);// 010120012
  • IntStream.range(0,x) – 0 (両端を含む) から x (両端を含まない) までの要素をストリームに出力します。

    地図:

    Stream.of(2, 3, 0, 1, 3)
            .map(x -> IntStream.range(0, x))
            .forEach(System.out::print);//list of streams (streams);
  • limit(long maxSize) – 要素の数によってストリームを制限します。

    stream.limit(5).forEach(x -> System.out.println(x));
  • Skip(long n) – n 要素をスキップします。

    stream.skip(3).forEach(x -> System.out.println(x));
  • ソート済み()

  • sorted(Comparator comparator) – ストリームを並べ替えます (TreeMap のように並べ替えます)。

    stream.sorted().forEach(x -> System.out.println(x));
  • unique() — ストリームの要素の一意性をチェックします (要素の繰り返しを削除します)。

  • dropwhile(Predicate predicate) - 条件を満たす要素をスキップします (Java 9 で登場しました。Predicate<T> 関数インターフェイスは、条件が満たされているかどうかを確認します。満たされている場合は、true が返されます。ラムダ式は、次の型のオブジェクトを受け取ります)パラメータとしての T:

    Predicate<Integer> isPositive = x -> x > 0;
           System.out.println(isPositive.test(3)); // true
           System.out.println(isPositive.test(-9)); // false
端末オペレーター:
ストリームAPI - 8
  • forEach(Consumer action) – for each の類似物 (Consumer<T> は何も返さずに、型 T のオブジェクトに対して何らかのアクションを実行します)。

  • count() – ストリーム要素の数を返します。

    System.out.println(stream.count());

  • collect(Collector コレクター) – すべての要素をリスト、セット、またはその他のコレクションに収集し、何らかの基準に従って要素をグループ化し、すべてを文字列に結合するメソッドです。

    List<String> list = Stream.of(One,Two,Three).collect(Collectors.toList());
  • collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)— と同じで、collect(collector)便宜上パラメータのみが分割されています(supplier新しいオブジェクト(コンテナ)を提供します。たとえばnew ArrayList()accumulatorコンテナに要素を追加し、combinerストリームの一部を結合します)。

  • reduce(Tidentity,BinaryOperatoraccumulator) - ストリームのすべての要素を 1 つのオブジェクトに変換し (すべての要素の合計を計算するか、最小要素を見つけます)、まずオブジェクトidentityとストリームの最初の要素を取得し、関数を適用するaccumulatoridentity次のようになります。その結果。その後、残りの要素についてすべてが続行されます。

    int sum = Stream.of(1, 2, 3, 4, 5).reduce(10, (acc, x) -> acc + x);// = 25
  • reduce(BinaryOperator accumulator)— 上記と同じメソッドですが、最初のメソッドがありませんidentity。これはストリームの最初の要素です。

    Optional min(Comparator comparator)
    オプションの max(Comparator コンパレータ) は、渡されたコンパレータに基づいて最小/最大要素を検索します。

  • findFirst()– ストリームの最初の要素を取り出します。

    Stream.of(1, 2, 3, 4, 9).findFirst();
  • allMatch(Predicate predicate)—ストリームのすべての要素が条件を満たす場合にtrueを返します。述語関数の呼び出し結果がfalseである要素が見つかった場合、演算子は要素のスキャンを停止し、falseを返します。

    Stream.of(1, 2, 3, 4, 9).allMatch(x -> x <= 7);//false
  • anyMatch(Predicate predicate)—ストリームの少なくとも 1 つの要素が条件を満たす場合にtrueを返しますpredicate

    Stream.of(1, 2, 3, 4, 9).anyMatch(x -> x >= 7);//true
  • noneMatch(Predicate predicate)—ストリームのすべての要素を調べた結果、どれも条件を満たさなかった場合にtrueを返しますpredicate

    Stream.of(1, 2, 3, 4, 9).noneMatch(x -> x >= 7);//false
最後に、いくつかの方法を見ていきたいと思いますCollectors
  • toList()— 要素を以下に収集しますList

    List<Integer> list = Stream.of(99, 2, 3).collect(Collectors.toList());
  • toSet()— 要素をセットに収集します。

    Set<Integer> set = Stream.of(99, 2, 3).collect(Collectors.toSet());
  • counting()— 要素の数をカウントします。

    Long count = Stream.of("1", "2", "3", "4").collect(Collectors.counting());
  • joining()

  • joining(CharSequence delimiter)

  • joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)— 要素を 1 行にまとめます。さらに、シーケンス全体の区切り文字、接頭辞と接尾辞を指定できます。

    String a = Stream.of("s", "u" ,"p", "e", "r").collect(Collectors.joining());
           System.out.println(a); // super
    
           String b = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining("-"));
           System.out.println(b); // s-u-p-e-r
    
           String c = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining(" -> ", "[ ", " ]"));
           System.out.println(c);  // [ s -> u -> p -> e -> r ]
  • summingInt(ToIntFunction mapper)

  • summingLong(ToLongFunction mapper)

  • summingDouble(ToDoubleFunction mapper)- オブジェクトを int/long/double に変換し、合計を計算するコレクター。

役立つリンク: PS: 恥ずかしがらずに「いいね」をたくさん送ってください ^ : ^
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION