Removing Elements from Java Collections

概要

このクイックチュートリアルでは、Java コレクションから特定の述語に一致するアイテムを削除する 4 つの異なる方法についてお話します。

Defining Our Collection

最初に、元のデータ構造を変更する 2 つのアプローチを説明します。

異なる方法を使用して同じ結果を達成する方法を示すために、この例を通して次のコレクションを使用しましょう。

これを行うには、まず iterator メソッドを使用して、その要素に対するイテレータを取得する必要があります。

Iterator<String> i = names.iterator();while(i.hasNext()) { String e = i.next(); if (e.startsWith("A")) { i.remove(); }}

その単純さにもかかわらず、考慮すべきいくつかの注意点があります。

  • コレクションによっては ConcurrentModificationException 例外に遭遇するかもしれません
  • それらを削除できる前に要素に対して反復する必要があります
  • コレクションによっては remove が期待とは異なる動作をする可能性があります。 例. ArrayList.Iterator はコレクションから要素を削除し、後続のデータを左にシフトしますが、LinkedList.Iterator は次の要素へのポインタを単に調整します。 そのため、LinkedList.Iterator は、アイテムを削除するときに ArrayList.Iterator よりもはるかに優れたパフォーマンスを発揮します

Java 8 と Collection.removeIf()

Java 8 では、Predicate:

names.removeIf(e -> e.startsWith("A"));

Iterator のアプローチとは逆に、LinkedList と ArrayList の両方で removeIf は同様によく実行することが重要なポイントになります。

Java 8 では、ArrayList は Iterator に依存するデフォルトの実装をオーバーライドし、異なる戦略を実装します。まず、要素に対して反復処理を行い、述部に一致するものをマークし、その後、最初の反復処理でマークされた要素を削除 (およびシフト) するために 2 回目の反復処理を行います。

Java 8 と Stream の導入

Java 8 の新しい主要機能の 1 つに、Stream (と Collector) が追加されました。 ソースから Stream を作成する方法はたくさんあります。 しかし、Stream インスタンスに影響を与えるほとんどの操作はそのソースを変更しません。むしろ、API はソースのコピーを作成し、その中で必要な任意の操作を実行することに焦点を合わせます。 Stream を使用して要素を削除する

Streamを使用した要素の削除というかフィルタリングは非常に簡単で、コレクションを使用してStreamのインスタンスを作成し、Predicateでフィルターを呼び出し、コレクターの助けを借りてその結果を収集するだけです。 しかし、アプリケーションで使用されるメモリも増加することに留意する必要があります。

5.2. Collectors.partitioningBy

Stream.filter と Collectors の両方を組み合わせることは非常に便利ですが、一致する要素と一致しない要素の両方が必要なシナリオに遭遇することがあります。 このメソッドは 2 つのキー、true と false のみを含む Map を返し、それぞれが一致する要素と一致しない要素を含むリストを指します。

Conclusion

この記事では、コレクションから要素を削除するいくつかの方法とその注意点について見てきました。

コメントを残す

メールアドレスが公開されることはありません。