Stream(Java1.8)の使い方を詳しく紹介

Stream は Java 8 API によって追加された新しい抽象化であり、stream Stream と呼ばれ、宣言的な方法でデータ コレクションを処理します (ソース データ コンピューティング機能のカプセル化に重点を置き、逐次操作と並列操作の両方をサポートします)。

ストリームは、データ処理操作をサポートするソースから生成される一連の要素です。ソースには、配列、ファイル、コレクション、関数などがあります。ストリームはコレクション要素ではなく、データ構造でもデータを保存しません。その主な目的は計算です。

ストリーム ストリームは、コレクション (コレクション) オブジェクトの機能を拡張したもので、ラムダ式と組み合わせることで、プログラミングの効率、間接化、およびプログラムの可読性を向上させることができます。

特徴

1. コードが簡潔である: 関数型プログラミングで書かれたコードは簡潔で、意図が明確です。ストリーム インターフェイスを使用すると、for ループに別れを告げることができます。

2. マルチコア対応: Java 関数型プログラミングを使用すると、メソッドを呼び出すだけで並列プログラムを簡単に作成できます。

プロセス

1. コレクションをストリームに変換します (またはストリームを作成します)。

2. ストリームの操作(中間操作、終了操作)

ストリームはパイプラインの中間操作によって処理され、最終的に前の処理の結果が終端操作によって取得されます。

インターフェースの継承関係

BaseStream: ストリーム管理のコアメソッドを宣言する基本インターフェイス。

ストリーム: コア インターフェイス。ストリーム操作のコア メソッドを宣言します。その他のインターフェイスは、指定された型を適応させたものです。

1. ストリーム作成操作

ストリームを生成するには主に 5 つの方法があります

1. ストリームの作成

Stream<整数> stream1 = Stream.of(1,2,3,4,5);

2. コレクション コレクションの作成 (アプリケーションで最もよく使用されるもの)

List<Integer> integerList = new ArrayList<>();

        integerList.add(1);

        integerList.add(2);

        integerList.add(3);

        integerList.add(4);

        integerList.add(5);

        Stream<Integer> listStream = integerList.stream();

3. 配列配列の作成

int[] intArr = {1, 2, 3, 4, 5};

        IntStream arrayStream = Arrays.stream(intArr);

ストリームは Arrays.stream メソッドによって生成され、このメソッドによって生成されたストリームは Stream ではなく数値ストリーム [つまり IntStream] です。

ノート:

数値ストリームを使用すると、計算中のアンボックス化とボックス化を回避し、パフォーマンスを向上させることができます。

Stream API は、オブジェクト ストリーム [つまり Stream] を対応する数値ストリームに変換するための 3 つの方法として、mapToInt、mapToDouble、mapToLong を提供し、数値ストリームをオブジェクト ストリームに変換するためのボックス化されたメソッドを提供します。

4. ファイルの作成

試す {

            Stream<String> fileStream = Files.lines(Paths.get("data.txt"), Charset.defaultCharset());

        } キャッチ (IOException e) {

            e.printStackTrace();

        }

Files.line メソッドを通じてストリームを取得します。取得された各ストリームは、指定されたファイル内の 1 行になります。

5. 関数の作成

イテレータ

Stream<Integer> iterateStream = Stream.iterate(0, n -> n + 2).limit(5);

iterate メソッドは 2 つのパラメーターを受け入れます。1 つ目は初期化値、2 つ目は実行される関数操作です。反復子によって生成されるフローは無限フローであり、フローはlimit メソッドによって切り捨てられ、5 つの偶数のみが生成されるためです。

発生器

Stream<Double>generateStream = Stream.generate(Math::random).limit(5);

生成メソッドは 1 つのパラメーターを受け入れます。メソッドのパラメーターのタイプは Supplier で、ストリームの値を提供します。generate によって生成されたストリームも無限ストリームであるため、ストリームは制限によって切り捨てられます。

2、オペレーター

ストリーム操作には、中間演算子と端末演算子の 2 つの主なタイプがあります。

(1) 中間オペレータ

一般に、Stream の中間操作はソース クエリとみなすことができ、遅延設計になっており、データベースのビューの原理と同様に、ソース データの計算は必要な場合にのみ実行されます。

Stream の利点は、豊富な中間操作を提供することで、コレクションや配列などのコンテナーと比較してソース データの計算の複雑さが大幅に簡素化されることです。

ストリームの後には、0 個以上の中間操作を続けることができます。その目的は主に、ストリームを開き、ある程度のレベルのデータ マッピング/フィルタリングを実行し、次の操作で使用する新しいストリームを返すことです。

この種の操作は不活性です。この種のメソッドを呼び出すだけでは、実際にはストリームの走査は開始されません。実際の走査は、終了操作まで待つ必要があります。一般的な中間操作には、以下で紹介するフィルター、マップなどが含まれます。

ストリーム方式 意味 例

filter は、条件を設定して要素を除外するために使用されます。  

リスト文字列 = Arrays.asList(“abc”, “”, “bc”, “efg”, “abcd”,"", “jkl”);

フィルターされたリスト = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

map は関数を引数として受け取ります。この関数は各要素に適用され、新しい要素にマッピングされます (変換と似ているためマッピングという言葉が使用されていますが、微妙な違いは、「変更する」のではなく「新しいバージョンを作成する」ということです)。  

リスト文字列 = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);

マップされたリスト = strings.stream().map(str->str+"-itcast").collect(Collectors.toList());

異なる要素を含むストリームを返します (ストリームによって生成された要素の hashCode メソッドと等しいメソッドに従って) Listnumbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);numbers.stream().filter(i -> i % 2 == 0).distinct().forEach(System.out::println);

ソートされたストリームはソートされて返されます

リスト文字列1 = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

リストのsorted1 = strings1.stream().sorted().collect(Collectors.toList());

制限は指定された長さを超えないストリームを返します  

リスト文字列 = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);

リスト限定 = strings.stream().limit(3).collect(Collectors.toList());

Skip は、最初の n 要素が破棄されたストリームを返します。  

リスト文字列 = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);

スキップされたリスト = strings.stream().skip(3).collect(Collectors.toList());

flatMap flatMap メソッドを使用すると、各配列がストリームにマップされず、ストリームのコンテンツにマップされるという効果があります。map(Arrays::stream) の使用時に生成されたすべての個別のストリームが結合されます。つまり、1 つのストリームに平坦化されます。

リスト文字列 = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);

ストリーム flatMap = strings.stream(). flatMap(Java8StreamTest::getCharacterByString);

要素を横断するピーク  

リスト文字列 = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);

文字列 .stream().peek(str-> str + "a").forEach(System.out::println);

    public static void main(String[] args) {

        List<User> userList = getUserList();

    }

    private static List<User> getUserList() {

        List<User> userList = new ArrayList<>();

        userList.add(new User(1,"張三",18,"上海"));

        userList.add(new User(2,"王呉",16,"上海"));

        userList.add(new User(3,"Lisi",20,"上海"));

        userList.add(new User(4,"張磊",22,"北京"));

        userList.add(new User(5,"張超",15,"深セン"));

        userList.add(new User(6,"リーレイ",24,"北京"));

        userList.add(new User(7,"主",21,"上海"));

        userList.add(new User(8,"張三峰",18,"広州"));

        userList.add(new User(9,"趙劉",16,"広州"));

        userList.add(new User(10,"趙武起",26,"深セン"));

        userList を返します。

    }

1. フィルター; フィルター

条件を設定して要素を除外するために使用されます

//1、フィルター: ID が 6 より大きいユーザー オブジェクトを出力します

List<ユーザー> filetrUserList = userList.stream().filter(user -> user.getId() > 6).collect(Collectors.toList());

filetrUserList.forEach(System.out::println);

2、地図

関数を引数として受け取ります。この関数は各要素に適用され、新しい要素にマッピングされます (変換と似ているためマッピングという言葉が使用されていますが、微妙な違いは、「変更する」のではなく「新しいバージョンを作成する」ということです)。

//2、マップ

List<String> mapUserList = userList.stream().map(user -> user.getName() + "用户").collect(Collectors.toList());

mapUserList.forEach(System.out::println);


 

3. 個別: 重複排除

さまざまな要素を含むストリームを返します (ストリームによって生成された要素の hashCode メソッドおよび等しいメソッドに従って実装されます)。

//3、個別: 重複排除

List<String> uniqueUsers = userList.stream().map(User::getCity).distinct().collect(Collectors.toList());

uniqueUsers.forEach(System.out::println);


 

4、並べ替え

ソートされたストリームを返します

//4、sorted: ソート、名前に従って逆順

userList.stream().sorted(Comparator.comparing(User::getName).reversed()).collect(Collectors.toList()).forEach(System.out::println);

5、制限

指定された長さまでのストリームを返します

//5, 制限: 最初の 5 個のデータを取得します

userList.stream().limit(5).collect(Collectors.toList()).forEach(System.out::println);


 

6、スキップ

最初の n 要素が破棄されたストリームを返します

//6、スキップ: 最初の数個をスキップし、次の数個を取得します

userList.stream().skip(7).collect(Collectors.toList()).forEach(System.out::println);

7、フラットマップ

flatMap メソッドを使用すると、各配列がストリームではなくストリームのコンテンツにマップされるという効果があります。map(Arrays::stream) の使用時に生成されたすべての個別のストリームが結合されます。つまり、1 つのストリームに平坦化されます。

//7、 flatMap: データ分割 1 対多マッピング

userList.stream(). flatMap(user -> Arrays.stream(user.getCity().split(","))).forEach(System.out::println);

マップ: ストリーム内の各要素を処理します

flatMap: ストリームの平坦化。あるストリームの「すべての値」を別のストリームに置き換えて、すべてのストリームを 1 つのストリームに接続できるようにします。

本質的な違い: マップは第 1 レベルの要素で動作し、フラットマップは第 2 レベルの要素で動作して値を返します。フラットマップは複数の値を持つストリームを返します。

アプリケーション シナリオ: マップはコレクション内の各要素を処理し、処理結果を返します。フラットマップはコレクション内の各要素を処理し、フラット化処理 (階層を分割し、同じレイヤーに置く) を実行してから返します。

8、覗く

要素を反復処理する

//8、ピーク: 要素を走査し、各ユーザー ID と 1 つの出力を追加します。

userList.stream().peek(user -> user.setId(user.getId()+1)).forEach(System.out::println);


 

(2) 端末オペレータ

Stream ストリームが端末操作を実行した後は、他のアクションを実行できません。そうでない場合は、ストリームが実行されたか閉じられたことを示すステータス例外が報告されます。操作を再度実行したい場合は、Stream ストリームを再作成する必要があります。

ストリームには終端操作が 1 つしかありません。この操作が実行されると、ストリームは閉じられ、それ以上操作できなくなります。したがって、ストリームを走査できるのは 1 回だけです。ストリームを走査したい場合は、ソース データを通じてストリームを生成する必要があります。

端末操作を実行すると、実際にストリームのトラバースが開始されます。数える、集めるなど。

ストリーム方式 意味 例

コレクターを収集し、ストリームを他の形式に変換します  

リスト文字列 = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

セット set = strings.stream().collect(Collectors.toSet());

リスト list = strings.stream().collect(Collectors.toList());

Map<String, String> map = strings.stream().collect(Collectors.toMap(v ->v.concat("_name"), v1 -> v1, (v1, v2) -> v1));

forEach 遍历流 List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);strings.stream().forEach(s -> out.println(s));

findFirst は最初の要素を返します

リスト文字列 = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

オプションの first = strings.stream().findFirst();

findAny は現在のストリーム内の任意の要素を返します    

リスト文字列 = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

オプションの any = strings.stream().findAny();

count はストリーム内の要素の合計数を返します。    

リスト文字列 = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

長いカウント = strings.stream().count();

sum 求和 int sum = userList.stream().mapToInt(User::getId).sum();

max 最大値 int max = userList.stream().max(Comparator.comparingInt(User::getId)).get().getId();

min 最小値 int min = userList.stream().min(Comparator.comparingInt(User::getId)).get().getId();

anyMatch は少なくとも 1 つの要素が一致するかどうかをチェックし、ブール値を返します  

リスト文字列 = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

boolean b = strings.stream().anyMatch(s -> s == “abc”);

allMatch はすべての要素が一致するかどうかをチェックし、ブール値を返します    

リスト文字列 = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

boolean b = strings.stream().allMatch(s -> s == “abc”);

noneMatch はすべての要素が一致しないかどうかをチェックし、ブール値を返します  

リスト文字列 = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

boolean b = strings.stream().noneMatch(s -> s == “abc”);

reduce はストリーム内の要素を繰り返し結合して値を取得できます

リスト文字列 = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

オプションのreduce = strings.stream().reduce((acc,item) -> {return acc+item;});if(reduce.isPresent())out.println(reduce.get());

1、集める

ストリームを他の形式に変換するコレクター

//1、collect: コレクター、ストリームを他の形式に変換します

        セット set = userList.stream().collect(Collectors.toSet());

        set.forEach(System.out::println);

        System.out.println("--------------------------");

        リストリスト = userList.stream().collect(Collectors.toList());

        list.forEach(System.out::println);

2、それぞれ

流れを横切る

//2、forEach: ストリームを走査します

userList.stream().forEach(user -> System.out.println(user));

userList.stream().filter(user -> "上海".equals(user.getCity())).forEach(System.out::println);

3、まず探す

最初の要素を返します

//3、findFirst: 最初の要素を返す

ユーザー firstUser = userList.stream().findFirst().get();

ユーザー firstUser1 = userList.stream().filter(user -> "上海".equals(user.getCity())).findFirst().get();

4、任意の検索

現在のストリーム内の任意の要素を返します

//4、findAny: 現在のストリーム内の任意の要素を返します

ユーザー findUser = userList.stream().findAny().get();

ユーザー findUser1 = userList.stream().filter(user -> "上海".equals(user.getCity())).findAny().get();

5、カウント

ストリーム内の要素の総数を返します。

//5, count: ストリーム内の要素の総数を返します

長いカウント = userList.stream().filter(user -> user.getAge() > 20).count();

System.out.println(count);

6、和

総括する

//6, 合​​計: 合計

int sum = userList.stream().mapToInt(User::getId).sum();

7、最大

最大値

//7, max: 最大値

int max = userList.stream().max(Comparator.comparingInt(User::getId)).get().getId();

8、分

最小値

//8, min: 最小値

int min = userList.stream().min(Comparator.comparingInt(User::getId)).get().getId();

9、任意の一致

少なくとも 1 つの要素が一致するかどうかを確認し、ブール値を返します

//9, anyMatch: 少なくとも 1 つの要素が一致するかどうかを確認します

boolean matchAny = userList.stream().anyMatch(user -> "北京".equals(user.getCity()));

10、オールマッチ

すべての要素が一致するかどうかを確認し、ブール値を返します

//10, allMatch: すべての要素が一致するかどうかを確認します

boolean matchAll = userList.stream().allMatch(user -> "北京".equals(user.getCity()));

11、なし一致

すべての要素が一致していないかどうかを確認し、ブール値を返します

//11、noneMatch: すべての要素が一致しないかどうかを確認し、ブール値を返します

boolean nonaMatch = userList.stream().allMatch(user -> "云南".equals(user.getCity()));

12、減らす

ストリーム内の要素を繰り返し結合して値を取得できます。

        //12、reduce: ストリーム内の要素を繰り返し結合して値を取得します

        オプションのreduce = userList.stream().reduce((user, user2) -> {

            リターンユーザー。

        });

        if(reduce.isPresent()) System.out.println(reduce.get());

3.収集コレクション

コレクター: 結果収集戦略のコア インターフェイス。指定された要素を結果コンテナーに蓄積して保存する機能があり、コレクター ツールでコレクター インターフェイスの実装クラスを提供します。

1、リストへ

ユーザー ID を List コレクションに保存します

List<Integer> idList = userList.stream().map(User::getId).collect(Collectors.toList()) ;

2、地図へ

ユーザー ID と名前を Key-Value 形式で Map コレクションに保存します。

Map<Integer,String> userMap = userList.stream().collect(Collectors.toMap(User::getId,User::getName));

3、セットする

ユーザーの都市を Set コレクションに保存します

Set<String> citySet = userList.stream().map(User::getCity).collect(Collectors.toSet());

4、数える

対象ユーザーの合計

長いカウント = userList.stream().filter(user -> user.getId()>1).collect(Collectors.counting());

5、合計Int

結果要素、つまりユーザーIDを合計します。

整数 sumInt = userList.stream().filter(user -> user.getId()>2).collect(Collectors.summingInt(User::getId)) ;

6、マイシティ

要素内の最小の ID を持つユーザーをフィルターします。

ユーザー maxId = userList.stream().collect(Collectors.minBy(Comparator.comparingInt(User::getId))).get() ;

7、入会

ユーザーの都市を指定された区切り記号で文字列に連結します。

String joinCity = userList.stream().map(User::getCity).collect(Collectors.joining("||"));

8、グループ化による

条件ごとにグループ化し、ユーザーを都市ごとにグループ化します。

Map<String,List<User>> groupCity = userList.stream().collect(Collectors.groupingBy(User::getCity));

1、orElse(null)

    /**

     * 存在する場合は値を返し、存在しない場合は {@code other} を返します。

     *

     * @param other 値が存在しない場合に返される値。

     * null であること

     * @存在する場合は値を返し、存在しない場合は {@code other}

     * 存在する場合は値を返し、それ以外の場合はその他を返します

     */

    public T orElse(T other) {

        戻り値 != null ? 値: その他;

    }

何も見つからない場合は null を返すことを示します (デフォルト値は orElse() に挿入できます。見つからない場合は、orElse に設定されたデフォルト値を返します)。

2、orElseGet(null)

    /**

     * 存在する場合は値を返し、存在しない場合は {@code other} を呼び出して戻ります

     * その呼び出しの結果。

     *

     * @param other {@code Supplier}。値がない場合に結果が返されます。

     * が存在します

     * @存在する場合は値を返し、それ以外の場合は {@code other.get()} の結果を返します。

     * 値が存在せず、{@code other} が存在する場合は @throws NullPointerException

     * ヌル

     * 存在する場合は値を返し、そうでない場合は他の値を呼び出し、その呼び出しの結果を返します。

     */

    public T orElseGet(Supplier<? extends T> other) {

        戻り値 != null ? 値: other.get();

    }

何も見つからない場合は null を返すことを示します (デフォルト値は orElseGet() に組み込むことができます。見つからない場合は、orElseGet に設定されたデフォルト値を返します)

orElse() は型 T の任意のパラメータを受け入れますが、orElseGet() は型 T のオブジェクトを返す Supplier 型の関数インターフェイスを受け入れます

orElse(null) と orElseGet(null) の違い:

1. 返されたオプション値が null の場合、orElse と orElseGet の両方が実行されます。

2. 返された Optional に値がある場合、orElse は実行されますが、orElseGet は実行されません

java.util.ArrayListをインポートします。

java.util.Listをインポートします。

インポート java.util.Optional;

java.util.stream.Collectorsをインポートします。

パブリック クラス TestStream {

    public static void main(String[] args) {

        List<User> list = new ArrayList<>();

        // 3 つのユーザー オブジェクトを定義します

        ユーザー user1 = 新しいユーザー();

        user1.setUserName("管理者");

        user1.setAge(16);

        user1.setSex("男");

        ユーザー user2 = 新しいユーザー();

        user2.setUserName("root");

        user2.setAge(20);

        user2.setSex("女性");

        ユーザー user3 = 新しいユーザー();

        user3.setUserName("管理者");

        user3.setAge(18);

        user3.setSex("男");

        ユーザー user4 = 新しいユーザー();

        user4.setUserName("admin11");

        user4.setAge(22);

        user4.setSex("女");

        // ユーザーをコレクションに追加します

        list.add(user1);

        list.add(user2);

        list.add(user3);

        list.add(user4);

        /*

        コレクション内のユーザー名に admin が含まれるコレクションをクエリします。

        */

        List<User> userList = list.stream().filter(user -> user.getUserName().contains("admin")

                            && user.getAge() <= 20).collect(Collectors.toList());

        System.out.println(userList);

        /*

        コレクション内の admin という名前の最初のユーザーをクエリします

        */

        Optional<User> user = list.stream().filter(userTemp -> "admin".equals(userTemp.getUserName())).findFirst();

        System.out.println(ユーザー);

        /*

        orElse(null) は、何も見つからない場合は null を返すことを意味します (デフォルト値は orElse() に挿入できます。見つからない場合は、orElse に設定されたデフォルト値に戻ります)。

        orElseGet(null) は、何も見つからない場合は null を返すことを意味します (デフォルト値は orElseGet() に挿入できます。見つからない場合は、orElseGet に設定されたデフォルト値を返します)。

        orElse() と orElseGet() の違い: メソッドを使用する場合、orElse のメソッドは値がなくても実行されますが、orElseGet は実行されません。

        */

        // 値なし

        ユーザー a = list.stream().filter(userT-> userT.getAge() == 12).findFirst().orElse(getMethod("a"));

        ユーザー b = list.stream().filter(userT11-> userT11.getAge() == 12).findFirst().orElseGet(()->getMethod("b"));

        //値がある

        ユーザー c = list.stream().filter(userT2-> userT2.getAge() == 16).findFirst().orElse(getMethod("c"));

        ユーザー d = list.stream().filter(userT22-> userT22.getAge() == 16).findFirst().orElseGet(()->getMethod("d"));

        System.out.println("a:"+a);

        System.out.println("b:"+b);

        System.out.println("c:"+c);

        System.out.println("d:"+d);

    }

    public static User getMethod(文字列名){

        System.out.println(名前 + "実行されたメソッド");

        null を返します。

    }

}


 

———————————————

元のリンク: https://blog.csdn.net/MinggeQingchun/article/details/123184273

おすすめ

転載: blog.csdn.net/m0_63364103/article/details/130136467