プライベートな連絡先の最初の情報
送料メール:
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Java 8 では多くの新機能が導入されており、その中で最も注目に値するのは Lambda 式と Stream API です。 Stream API は、収集データを処理するための効率的かつ簡潔な方法を提供し、コードをより簡潔かつ明確にし、可読性と保守性を高めます。この記事では、基本概念、一般的な操作、並列処理、実際のケース、ベスト プラクティスなど、Java Stream API の使用法について詳しく説明します。
Stream API は、コレクション データを処理するために Java 8 で導入された抽象化であり、(SQL ステートメントと同様の) 宣言的な方法でデータを処理できるようになります。 Stream API は、コレクションに対するフィルター、並べ替え、マッピング、リデュースなどの操作に使用できる多くの強力な操作を提供し、コードを大幅に簡素化します。
ストリーム API には、ストリームを作成するためのさまざまな方法が用意されており、一般的なものには次のようなものがあります。
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);
Stream.of
:Stream<String> stream = Stream.of("a", "b", "c");
Stream.generate
:Stream<Double> stream = Stream.generate(Math::random).limit(10);
Stream.iterate
:Stream<Integer> stream = Stream.iterate(0, n -> n + 2).limit(10);
中間操作はストリームの変換に使用され、遅延評価されます。一般的な中間操作には次のようなものがあります。
filter
: 要素をフィルタリングするために使用されます。Stream<String> stream = list.stream().filter(s -> s.startsWith("a"));
map
: 各要素を対応する結果にマッピングするために使用されます。Stream<String> stream = list.stream().map(String::toUpperCase);
flatMap
: 各要素をストリームに変換し、それを 1 つのストリームにマージするために使用されます。Stream<String> stream = list.stream().flatMap(s -> Stream.of(s.split("")));
distinct
: 重複を削除するために使用されます。Stream<String> stream = list.stream().distinct();
sorted
: 並べ替えに使用されます。Stream<String> stream = list.stream().sorted();
peek
: 処理中に各要素を表示するために使用されます。Stream<String> stream = list.stream().peek(System.out::println);
ターミナル操作は、ストリームの計算を開始し、結果を生成するために使用されます。一般的なターミナル操作には次のものがあります。
forEach
: 各要素に対して操作を実行します。list.stream().forEach(System.out::println);
collect
: ストリームを他の形式に変換します。List<String> result = list.stream().collect(Collectors.toList());
reduce
: ストリーム内の要素を値に還元します。Optional<String> result = list.stream().reduce((s1, s2) -> s1 + s2);
toArray
:ストリームを配列に変換します。String[] array = list.stream().toArray(String[]::new);
count
:要素数をカウントします。long count = list.stream().count();
anyMatch
、allMatch
、noneMatch
:マッチング判定に使用します。boolean anyMatch = list.stream().anyMatch(s -> s.startsWith("a"));
boolean allMatch = list.stream().allMatch(s -> s.startsWith("a"));
boolean noneMatch = list.stream().noneMatch(s -> s.startsWith("a"));
findFirst
、findAny
: 要素を検索するために使用されます。Optional<String> first = list.stream().findFirst();
Optional<String> any = list.stream().findAny();
使用sorted
このメソッドはストリームを並べ替え、コンパレーターに渡すことができます。
List<String> list = Arrays.asList("b", "c", "a");
List<String> sortedList = list.stream().sorted().collect(Collectors.toList());
// 逆序排序
List<String> sortedListDesc = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
使用filter
Stream内の要素をフィルタリングするメソッド。
List<String> list = Arrays.asList("a", "b", "c");
List<String> filteredList = list.stream().filter(s -> s.startsWith("a")).collect(Collectors.toList());
使用map
メソッドはストリーム内の要素をマップします。
List<String> list = Arrays.asList("a", "b", "c");
List<String> mappedList = list.stream().map(String::toUpperCase).collect(Collectors.toList());
使用reduce
ストリーム内の要素を削減するメソッド。
List<String> list = Arrays.asList("a", "b", "c");
String result = list.stream().reduce("", (s1, s2) -> s1 + s2);
使用collect
メソッドはストリームを他の形式に変換します。
List<String> list = Arrays.asList("a", "b", "c");
List<String> collectedList = list.stream().collect(Collectors.toList());
Set<String> collectedSet = list.stream().collect(Collectors.toSet());
String joinedString = list.stream().collect(Collectors.joining(","));
Parallel Stream はマルチコア CPU の利点を最大限に活用し、データ処理効率を向上させることができます。使えるparallelStream
メソッドは並列ストリームを作成します。
List<String> list = Arrays.asList("a", "b", "c");
List<String> parallelList = list.parallelStream().map(String::toUpperCase).collect(Collectors.toList());
も使用できますparallel
通常の Stream を並列 Stream に変換するメソッドです。
List<String> list = Arrays.asList("a", "b", "c");
List<String> parallelList = list.stream().parallel().map(String::toUpperCase).collect(Collectors.toList());
並列ストリームは常にシリアル ストリームより高速であるとは限らず、特定の状況に応じてテストする必要があることに注意してください。
文字列のコレクションが与えられた場合、長さが 3 未満の文字列をフィルターで除外し、残りの文字列を大文字に変換します。
List<String> list = Arrays.asList("a", "ab", "abc", "abcd");
List<String> result = list.stream()
.filter(s -> s.length() >= 3)
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(result); // 输出:[ABC, ABCD]
一連の整数を指定して、すべての整数の平均を計算します。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
OptionalDouble average = list.stream()
.mapToInt(Integer::intValue)
.average();
average.ifPresent(System.out::println); // 输出:3.0
ストリームAPIの使用
ファイルの内容を読み取り、コンソールに出力します。
try (Stream<String> lines = Files.lines(Paths.get("example.txt"))) {
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
ファイルの内容を読み取り、各単語の出現数を数えます。
try (Stream<String> lines = Files.lines(Paths.get("example.txt"))) {
Map<String, Long> wordCount = lines
.flatMap(line -> Arrays.stream(line.split("\W+")))
.collect(Collectors.groupingBy(String::toLowerCase, Collectors.counting()));
wordCount.forEach((word, count) -> System.out.println(word + ": " + count));
} catch (IOException e) {
e.printStackTrace();
}
データベーステーブルがあるとします。users
、フィールドを含むid
、name
そしてage
。 Stream API を使用してクエリ結果を処理できます。
List<User> users = queryDatabase();
List<String> names = users.stream()
.filter(user -> user.getAge() > 18)
.map(User::getName)
.collect(Collectors.toList());
System.out.println(names);
Collectors
このクラスにはさまざまなコレクターが用意されており、特定のニーズに応じて適切なコレクターを選択できます。ストリームを一度消費すると、再度使用することはできません。再利用する必要がある場合は、使用する前にストリームをコレクションに変換することを検討してください。
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
stream.forEach(System.out::println);
stream.forEach(System.out::println); // 会抛出IllegalStateException
並列ストリームは常にシリアル ストリームより高速であるとは限らないため、ケースバイケースでテストする必要があります。使えるForkJoinPool
並列ストリームのパフォーマンスを最適化します。
ForkJoinPool customThreadPool = new ForkJoinPool(4);
customThreadPool.submit(() ->
list.parallelStream().forEach(System.out::println)
).get();
Stream API を使用して大量のデータを処理する場合は、メモリ リークの問題に注意する必要があります。使えるclose
メソッドを使用してストリームを閉じるか、try-with-resources
ステートメントはストリームを自動的に閉じます。
try (Stream<String> lines = Files.lines(Paths.get("example.txt"))) {
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
この記事では、基本操作、高度な操作、並列処理、実践事例、ベストプラクティスなど、Java Stream API の使い方を詳しく紹介します。 Stream API を合理的に利用することで、開発者はコードを大幅に簡素化し、コードの可読性と保守性を向上させ、データ処理の効率も向上させることができます。この記事が Java 開発における Stream API の使用に役立つことを願っています。
Java Stream API は、収集データを処理するための強力なツールです。さまざまな操作を柔軟に使用することで、効率的なデータ処理とストリーミング コンピューティングを実現できます。 Stream API を使用したことがない場合は、できるだけ早くこの強力なツールを学習してマスターし、プロジェクトに適用して開発効率とコードの品質を向上させることをお勧めします。