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