JavaRush /Java Blog /Random-JA /コーヒーブレイク#108。12 Java ストリームの一般的な使用法、Java でオブジェクトのメモリ割り当てを評...

コーヒーブレイク#108。12 Java ストリームの一般的な使用法、Java でオブジェクトのメモリ割り当てを評価する方法

Random-JA グループに公開済み

Java ストリームを使用する 12 の一般的な方法

出典: Dev.to Java Streams API は Java 8 で初めて登場しました。その目的は、オブジェクトのコレクションに対して一般的な操作を実行するためのよりコンパクトな方法を提供することです。また、Java Streams API を使用して、複雑なアルゴリズムを実装することもできます。この記事では、Java Streams の一般的な使用例について説明します。 コーヒーブレイク#108。 12 Java ストリームの一般的な使用法、Java でオブジェクトのメモリ割り当てを評価する方法 - 1まず、いくつかの基本を明確にしましょう。
  • stream() - コレクションからストリームを作成します。

  • collect() - ストリームをオブジェクトに収集します。オブジェクトは、コレクション、プリミティブ、またはカスタム クラスにすることができます。

  • Collectors は、ストリームを収集するための (多数の) 静的メソッドを提供するクラスです。

次に、ストリームの使用例をいくつか見てみましょう。

1. フィルタリング

  • 条件に基づいてコレクションから値を削除するために使用されます。

  • 条件に基づいてコレクション要素をフィルタするには、filter()メソッドを使用します。一致する要素のみが保存されます。

例: リストからすべての奇数を削除します。
List<Integer> evenNumbers = originalList.stream()
        .filter(n -> n % 2 == 0)
        .collect(Collectors.toList());

2. 前処理

  • コレクション内のすべての値を適切に変更する必要がある場合に便利です。

  • map()メソッドは、コレクションの各要素に関数を適用し、計算された値の新しいコレクションを返すために使用されます。

たとえば、各値を 2 乗に変換してみましょう。
List<Integer> squares = originalList.stream()
        .map(n -> n * n)
        .collect(Collectors.toList());

3. 変換

  • コレクションを別のコレクションに変換する場合に便利です。

  • これを実現するにはいくつかの方法があります。

上で述べたように、 map() メソッドcollect()メソッドを使用して、コレクションを別のコレクションに変換できます。

例 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()メソッドは、コレクションの各要素に関数を適用し、単一の値を返すために使用されます。

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()メソッドは検索に使用されます。

これは通常、線形検索に似ています。たとえば、長さが 5 文字を超える、リスト内の最初の単語を探しています。
Optional<String> firstLongWord = words.stream()
        .filter(word -> word.length() > 5)
        .findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.

7. 仕分け

  • コレクションの要素を並べ替えます。

  • ソートにはsorted()メソッドが使用されます。

一般に、コレクションを並べ替えるには、 Collections.sort()で十分です。特に別の操作を実行したい場合は、sorted()を使用できます。たとえば、数値のリストを昇順に並べ替えて、最初の k 個の要素を返してみましょう。
List<Integer> topK = numbers.stream()
        .sorted()
        .limit(k)
        .collect(Collectors.toList());

8. パーティショニング

  • 指定された条件に基づいてコレクションの要素を分離します。

  • Collectors.partitioningBy()メソッドは、要素を分離するために使用されます。

スプリットはグループと似ていますが、条件に一致する要素と条件に一致しない要素の 2 つのコレクションを返す点が異なります。たとえば、学生を試験に合格した人と不合格者に分けてみましょう。
Map<Boolean, List<Student>> passingFailing = students
        .stream()
        .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));

9. カウンティング

  • 条件に一致する要素の数をカウントします。

  • count()メソッドは、条件に一致する要素の数をカウントするために使用されます。

たとえば、リスト内の長さが 5 文字を超える単語の数を数えてみましょう。
long count = words.stream()
        .filter(word -> word.length() > 5)
        .count();

10. 範囲

  • 値の範囲を作成します。

  • 値の範囲を作成するには、range()メソッドを使用します。

特定のタイプのストリーム ( IntStreamLongStreamDoubleStreamStream )を作成するための特別なクラスがあります。これらのクラスは、プリミティブ数値型を操作する場合に便利です。配列をストリームに変換するには、Arrays.stream()を使用します。たとえば、0 から 10 までの数値の配列を作成してみましょう。
int[] numbers = IntStream.range(0, 10).toArray();

11. マッチング

  • コレクションの要素を述語 (条件) と照合します。

  • anyMatch()allMatch()noneMatch()などのメソッドは、コレクション要素を述語と照合し、ブール値を返すために使用されます。

たとえば、価格が 10 より高い製品をチェックしてみましょう。
// 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()メソッドを使用します。

たとえば、リスト内のすべての単語を 1 つの文字列に連結してみましょう。
String joinedWords = words.stream()
        .collect(Collectors.joining(" "));
一般的なシナリオについては以上です。他にも、自分で検討できるあまり一般的ではないシナリオがあります。
  • 並列ストリーム。
  • 統計;
  • カスタムコレクター。

スレッドの利点

  • よりコンパクトなコード - コレクションの処理に必要なコードの量を削減します。

  • 中間変数が少なくなります。変数が介在すると、エラーが発生する可能性があります。数が少なければ少ないほど、予期せぬ間違いを避けるのが容易になります。

  • 直感的なコード。開発者の中には、スレッドが他のメソッドよりも直感的であることに同意しない人もいるでしょう。ただし、慣れてしまえば、他の方法よりもはるかに直感的になります。

読んでくれてありがとう。この記事を楽しんでいただければ幸いです。このトピックで説明されていないスレッドを使用できるケースは他にもたくさんあります。私が見逃した一般的なシナリオを自由に追加してください。

Java でオブジェクトのメモリ割り当てを評価する方法

出典: DZone この記事では、Java でオブジェクトのメモリ割り当てを評価する最もよく知られた 3 つの方法を示します。

プロファイラーを使用したメモリ評価

一部のオブジェクトのメモリを見積もる最も簡単な方法は、 Visual VMなどのプロファイラを使用して JVM メモリを直接調べることです。 コーヒーブレイク#108。 12 Java ストリームの一般的な使用法、Java でオブジェクトのメモリ割り当てを評価する方法 - 2このアプローチの問題は、実行中の 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 でのみサポートされていることに注意してください。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION