1. JavaストリームAPI
Java Stream 関数型プログラミング インターフェイスは Java 8 で初めて導入され、ラムダとともに Java 開発の画期的な機能となり、開発者のコレクション データ処理の効率を大幅に高めました。
Java Stream はデータが流れるパイプラインであり、データはパイプライン内で処理されてから次のパイプラインに流れます。Linux パイプラインを学習したことのある学生なら簡単に理解できるはずです。Java Stram が登場する前は、コレクション クラスの操作はほとんどが for ループを通じて実行されていました。次の記事からわかるように、Java Stream は for ループよりも簡潔で使いやすく、高速です。
パイプラインの機能には、フィルタ、マップ、並べ替えなどが含まれます。コレクション データは、Java Stream パイプラインを通じて処理された後、別のコレクション セットまたはデータ出力に変換されます。
2. ストリーム API による for ループの置き換え
まず例を見てみましょう。
List<String> nameStrs = Arrays.asList("Monkey", "Lion", "Giraffe","Lemur");
List<String> list = nameStrs.stream()
.filter(s -> s.startsWith("L"))
.map(String::toUpperCase)
.sorted()
.collect(toList());
System.out.println(list);
- まず、Stream() 関数を使用してリストをパイプライン ストリームに変換します。
- filter 関数を呼び出して配列要素をフィルタリングします。フィルタリング メソッドはラムダ式を使用します。L で始まる要素は true を返して保持され、他の List 要素はフィルタリングされます。
- 次に、Map 関数を呼び出してパイプライン ストリーム内の各要素を処理し、すべての文字を大文字に変換します。
- 次に、sort 関数を呼び出して、パイプライン ストリーム内のデータを並べ替えます。デフォルトでは、sorted() メソッドを使用して並べ替える場合、並べ替えは自然な順序で行われます。文字列の場合、自然な順序はアルファベットの昇順です。sorted() メソッドは、大文字に変換された文字列を並べ替えます。大文字は対応する小文字よりも Unicode 値が低いため、大文字が最初にソートされ、次に小文字がソートされます。
- 最後に、collect 関数 toList が呼び出されて、パイプライン ストリームが List に変換され、それが返されます。
最終的な出力は [キツネザル、ライオン] です。
もちろん、他のルールに基づいて並べ替える場合は、sorted(Comparator)
このメソッドを使用し、カスタム コンパレータを提供して並べ替えルールを指定できます。たとえば、sorted((str1, str2) -> str1.length() - str2.length())
文字列の長さで並べ替えるのに使用できます。
import java.util.Comparator;
public class StringLengthComparator implements Comparator<String> {
@Override
public int compare(String str1, String str2) {
return str1.length() - str2.length();
}
}
インターフェースStringLengthComparator
を実装する という 名前のクラスが作成されます。Comparator<String>
このインターフェイスでは、compare
要素間の順序付けルールを定義するメソッドを実装する必要があります。
このメソッドではcompare
、str1.length() - str2.length()
2 つの文字列の長さを比較するために使用します。str1
の長さが の長さより小さい場合str2
、負の値が返されます。str1
の長さが の長さより大きい場合はstr2
、正の値を返します。str1
と のstr2
長さが等しい場合は、0 を返します。メソッドnew StringLengthComparator()
に渡すことで文字列の長さで並べ替えることができます。sorted()
List<String> sortedList = nameStrs.stream()
.filter(s -> s.startsWith("L"))
.map(String::toUpperCase)
.sorted(new StringLengthComparator())
.collect(Collectors.toList());
System.out.println(sortedList);
もちろん、文字列のリストをソートするには Java 8 以前のメソッドを使用します。
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return b.compareTo(a);
}
});
ラムダ式を使用すると、次のような効果が得られます。
Collections.sort(names, (String a, String b) -> {
return b.compareTo(a);
});
// 只有一条逻辑语句,可以省略大括号
Collections.sort(names, (String a, String b) -> b.compareTo(a));
// 可以省略入参类型
Collections.sort(names, (a, b) -> b.compareTo(a));
3. 配列をパイプストリームに変換する
Stream.of() メソッドを使用して、配列をパイプ ストリームに変換します。
String[] array = {"Monkey", "Lion", "Giraffe", "Lemur"};
Stream<String> nameStrs2 = Stream.of(array);
Stream<String> nameStrs3 = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");
4. コレクションオブジェクトをパイプラインストリームに変換する
コレクション クラスの stream() メソッドを呼び出して、コレクション クラス オブジェクトをパイプライン ストリームに変換します。
List<String> list = Arrays.asList("Monkey", "Lion", "Giraffe", "Lemur");
Stream<String> streamFromList = list.stream();
Set<String> set = new HashSet<>(list);
Stream<String> streamFromSet = set.stream();
5. テキストファイルをパイプストリームに変換する
Files.lines メソッドを通じてテキスト ファイルをパイプライン ストリームに変換します。Paths.get() メソッドの機能はファイルを取得することです。これは Java NIO の API です。つまり、Java Stream を簡単に使用できますテキスト ファイルをロードして 1 行ずつ比較し、ファイルの内容が処理されます。
Stream<String> lines = Files.lines(Paths.get("file.txt"));
6. ストリーム化後の操作
配列または値のセットをストリームに変換すると、ストリームのさまざまな操作メソッドを使用してそれを処理および操作できます。以下に操作例をいくつか示します。
①. ストリーム内の要素を走査します。
Stream<String> nameStrs2 = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");
nameStrs2.forEach(System.out::println);
②. ストリーム内のフィルター要素:
Stream<String> nameStrs2 = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");
Stream<String> filteredStream = nameStrs2.filter(s -> s.startsWith("L"));
③. ストリーム内の要素を変換します。
Stream<String> nameStrs2 = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");
Stream<String> upperCaseStream = nameStrs2.map(String::toUpperCase);
④ ストリーム内の要素を並べ替えます。
Stream<String> nameStrs2 = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");
Stream<String> sortedStream = nameStrs2.sorted();
⑤. ストリーム内の要素に対して集計操作を実行します。
Stream<String> nameStrs2 = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");
Optional<String> longestString = nameStrs2.max(Comparator.comparingInt(String::length));
⑥. ストリーム内の要素をコレクションに収集します。
Stream<String> nameStrs2 = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");
List<String> stringList = nameStrs2.collect(Collectors.toList());