[JAVA構文]Stream paの表示


Stream vs Collections


1. conceptual difference


まずStreamとCollectionsの概念自体が違いますCollectionsは、データを収集およびグループ化するためのデータ構造です.例えば、List、Mapなど.
これとは異なり、Streamはこれらのグループに格納されたデータを処理することを目的としている.たとえば、リストのソートと出力です.

2.データ修正


また、収集はデータを変更または削除することができますが、Streamは入力されたデータセットのみを処理し、元のデータセットを置き換えることはできません.また,最初はこのような内部関数は存在しなかった.

3. External Iteration Vs Internal Iteration


コレクションは外部ループとして繰り返し表示され、Streamは内部で繰り返しを非表示にします.次の例は分かりやすいです
List<String> names = new ArrayList<>();
                 
names.add("Charlie");
                 
names.add("Douglas");
                 
names.add("Sundaraman");
                 
//External iteration of collections
         
for (String name : names) 
{
    System.out.println(name);
}
         
//Output :
         
//Charlie
//Douglas
//Sundaraman

         
//Internal iteration of streams. No for loops
 
names.stream().map(String::toUpperCase).forEach(System.out::println);
                 
//Output :
                 
//CHARLIE
//DOUGLAS
//SUNDARAMAN

4.旅行(ツアー)


Collectionsは複数回巡回できますが、Streamは1回の巡回が終了すると後続の巡回はできません.消費したことを表す.再スキャンする場合は、Streamを再作成する必要があります.
List<Integer> numbers = Arrays.asList(4, 2, 8, 9, 5, 6, 7);
         
Stream<Integer> numbersGreaterThan5 = numbers.stream().filter(i -> i > 5);
         
//Traversing numbersGreaterThan5 stream first time
         
numbersGreaterThan5.forEach(System.out::println);
         
//Second time traversal will throw error
         
//Error : stream has already been operated upon or closed
         
numbersGreaterThan5.forEach(System.out::println);

5. Eager Construction Vs Lazy Construction


最後にCollectionはすぐに作成され、Streamは必要に応じて作成され、terminate operationに遭遇するまで演算されません.

terminate vs intermediate


Streamの動作はStreamのterminate動作を終了することと残りの中間動作に分けられる.各アクションの定義を表示できます.
  • terminate : toArray(), forEach(), max(), min() ...
  • intermediate : limit(), sorted(), peek()...
  • stateful vs stateless


    次のコードは、Streamの実行状況を理解するのに役立ちます.
    List<String> list = new ArrayList<>(Arrays.asList("a","ab","abc","abcd"));
    
    Stream<Integer> stream = list.stream()
                    .map(i -> {
                        System.out.println("map " + i);
                        return i.length();
                    })
                    .peek(i -> System.out.println("check" + i))
                    .filter(i -> {
                        System.out.println("filter " + i);
                        return i % 2 == 0;
                    })
                    .sorted()
                    .peek(i -> System.out.println("sorted" + i));
    
    System.out.println("Invoking terminal method count.");
    System.out.println(stream.count());
    
    /* output
    Invoking terminal method count.
    map a
    check1
    filter 1
    map ab
    check2
    filter 2
    map abc
    check3
    filter 3
    map abcd
    check4
    filter 4
    sorted2
    sorted4
    2
    */
    遅延操作があるかどうかを確認するには、terminate operation countに最初に遭遇する必要があります.その後、手順に従って操作を行うことができます.
    しかし不思議なことに、すべての操作はソートの異なる操作の上で行われ、一度に集まってから順番に行われます.
    これはソートがソートであるため、1つずつ行うのではなく、全員が集まるまで待つためです.これもコードを直接定義する分類です.