Java ストリームを使用する 12 の一般的な方法
出典: Dev.to Java Streams API は Java 8 で初めて登場しました。その目的は、オブジェクトのコレクションに対して一般的な操作を実行するためのよりコンパクトな方法を提供することです。また、Java Streams API を使用して、複雑なアルゴリズムを実装することもできます。この記事では、Java Streams の一般的な使用例について説明します。 まず、いくつかの基本を明確にしましょう。-
stream() - コレクションからストリームを作成します。
-
collect() - ストリームをオブジェクトに収集します。オブジェクトは、コレクション、プリミティブ、またはカスタム クラスにすることができます。
-
Collectors は、ストリームを収集するための (多数の) 静的メソッドを提供するクラスです。
1. フィルタリング
-
条件に基づいてコレクションから値を削除するために使用されます。
-
条件に基づいてコレクション要素をフィルタするには、filter()メソッドを使用します。一致する要素のみが保存されます。
List<Integer> evenNumbers = originalList.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
2. 前処理
-
コレクション内のすべての値を適切に変更する必要がある場合に便利です。
-
map()メソッドは、コレクションの各要素に関数を適用し、計算された値の新しいコレクションを返すために使用されます。
List<Integer> squares = originalList.stream()
.map(n -> n * n)
.collect(Collectors.toList());
3. 変換
-
コレクションを別のコレクションに変換する場合に便利です。
-
これを実現するにはいくつかの方法があります。
例 1: リストからマップを作成します。
文字列のリストを文字列と長さのマップに変換します。Map<String, Integer> wordLengths = words.stream()
.collect(Collectors.toMap(
word -> word,
word -> word.length()));
例 2. リストをセットに変換します。
これは、重複を削除するための一般的な使用例です。さらに、要素をリストに戻したい場合は、stream() メソッドとcollect()メソッドを 2 回使用できます。たとえば、文字列のリストを一意の文字列のリストに変換してみましょう。// if we want to collect to a set
Set<String> uniqueWords = words.stream()
.collect(Collectors.toSet());
// OR
// if we want to start and end as a list
List<String> uniqueWords = words.stream()
.collect(Collectors.toSet()).stream().collect(Collectors.toList());
例 3. 製品のリストをその名前のリストに変換します。(平坦化 - 整列)
List<String> productNames = products.stream()
.map(product -> product.getName())
.collect(Collectors.toList());
4. 削減
-
Collection を単一の値に削減します。
-
reduce()メソッドは、コレクションの各要素に関数を適用し、単一の値を返すために使用されます。
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
5. グループ化
-
指定された条件に基づいてコレクションの要素をグループ化します。
-
Collection 要素を条件別にグループ化するには、Collectors.groupingBy()メソッドを使用します。
Map<String, List<Product>> productsByCategory = products.stream()
.collect(Collectors.groupingBy(product -> product.getCategory()));
6. 発見
-
条件に一致する最初の Collection 要素または任意の Collection 要素を検索します。
-
findFirst()メソッドとfindAny()メソッドは検索に使用されます。
Optional<String> firstLongWord = words.stream()
.filter(word -> word.length() > 5)
.findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.
7. 仕分け
-
コレクションの要素を並べ替えます。
-
ソートにはsorted()メソッドが使用されます。
List<Integer> topK = numbers.stream()
.sorted()
.limit(k)
.collect(Collectors.toList());
8. パーティショニング
-
指定された条件に基づいてコレクションの要素を分離します。
-
Collectors.partitioningBy()メソッドは、要素を分離するために使用されます。
Map<Boolean, List<Student>> passingFailing = students
.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
9. カウンティング
-
条件に一致する要素の数をカウントします。
-
count()メソッドは、条件に一致する要素の数をカウントするために使用されます。
long count = words.stream()
.filter(word -> word.length() > 5)
.count();
10. 範囲
-
値の範囲を作成します。
-
値の範囲を作成するには、range()メソッドを使用します。
int[] numbers = IntStream.range(0, 10).toArray();
11. マッチング
-
コレクションの要素を述語 (条件) と照合します。
-
anyMatch()、allMatch()、noneMatch()などのメソッドは、コレクション要素を述語と照合し、ブール値を返すために使用されます。
// true when all elements match the predicate
boolean allMatch = products.stream()
.allMatch(product -> product.getPrice() > 10);
// true when any element matches the predicate
boolean anyMatch = products.stream()
.anyMatch(product -> product.getPrice() > 10);
// true when no elements match the predicate
boolean noneMatch = products.stream()
.noneMatch(product -> product.getPrice() > 10);
12. 参加
-
コレクションの要素を文字列に連結します。
-
コレクション要素を文字列に結合するには、Collectors.joining()メソッドを使用します。
String joinedWords = words.stream()
.collect(Collectors.joining(" "));
一般的なシナリオについては以上です。他にも、自分で検討できるあまり一般的ではないシナリオがあります。
- 並列ストリーム。
- 統計;
- カスタムコレクター。
スレッドの利点
-
よりコンパクトなコード - コレクションの処理に必要なコードの量を削減します。
-
中間変数が少なくなります。変数が介在すると、エラーが発生する可能性があります。数が少なければ少ないほど、予期せぬ間違いを避けるのが容易になります。
-
直感的なコード。開発者の中には、スレッドが他のメソッドよりも直感的であることに同意しない人もいるでしょう。ただし、慣れてしまえば、他の方法よりもはるかに直感的になります。
Java でオブジェクトのメモリ割り当てを評価する方法
出典: DZone この記事では、Java でオブジェクトのメモリ割り当てを評価する最もよく知られた 3 つの方法を示します。プロファイラーを使用したメモリ評価
一部のオブジェクトのメモリを見積もる最も簡単な方法は、 Visual VMなどのプロファイラを使用して JVM メモリを直接調べることです。 このアプローチの問題は、実行中の JVM に接続する必要があることですが、セキュリティ上の理由により実稼働環境では接続できない場合があります。機器を使用した記憶評価
特定のオブジェクトに割り当てられたメモリを推定するもう 1 つの方法は、インストゥルメントを使用することです。簡単に言えば、クラスを作成し、それを JAR にコンパイルする必要があります。JAR を作成した後、その JAR とともに JVM を実行する必要があります。この方法の詳細については、こちらをご覧ください。ここでの欠点は、特定の jar ファイルを JVM に追加する必要があることであり、セキュリティまたは関連する問題により、実稼働環境では受け入れられない可能性があります。JOLライブラリを使用したメモリ評価
別のオプションとして、 JOL ライブラリを使用できます。これは、オブジェクトの重みとオブジェクト インスタンスによって割り当てられたメモリの詳細な推定を提供できる非常に強力なライブラリです。ライブラリを使用するには、依存関係を追加する必要があります。<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.16</version>
</dependency>
その後、次のように使用できます。
out.println(GraphLayout.parseInstance(myObject).totalSize() / 1024000d + " MB")
Twitter アーカイブの ObjectSizeCalculator
Twitter のパブリックGitHubリポジトリには、特定のオブジェクト インスタンスに割り当てられたメモリを推定できるObjectSizeCalculator と呼ばれるツール クラスがあります。使用するのに多くのメモリや時間を必要としません。評価プロセスには、大きなオブジェクトであっても数秒かかります。このクラスの使用は非常に簡単です。ObjectSizeCalculator.getObjectSize(address)
この方法をお勧めしますが、この方法は Java Hotspot、OpenJDK、TwitterJDK でのみサポートされていることに注意してください。
GO TO FULL VERSION