1概要

このクイックチュートリアルでは、** 特定の述語に一致するアイテムをJavaから削除するための4つの異なる方法について説明します。

当然ながら、いくつかの注意事項も確認します。


2コレクションを定義する

まず、元のデータ構造を変化させる2つのアプローチを説明します。それから、アイテムを削除する代わりに、それらなしでオリジナルの

Collection

のコピーを作成する2つの他のオプションについて話します。

例を通して、次のコレクションを使用して、さまざまな方法で同じ結果を達成する方法を説明しましょう。

Collection<String> names = new ArrayList<>();
names.add("John");
names.add("Ana");
names.add("Mary");
names.add("Anthony");
names.add("Mark");


3

Iterator


を使用した要素の削除

そのためには、まず


iterator


メソッドを使用して、その要素のイテレータを取得する必要があります。 。その後、https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html#next–[

next

]を使用して各要素にアクセスし、

https:/を使用してそれらを削除できます。/docs.oracle.com/javase/8/docs/api/java/util/Iterator.html#remove–[remove]

:

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

よりもはるかに優れたパフォーマンスを発揮します。


4 Java 8と

Collection.removeIf()


Java 8では、

httpsを使用して要素を削除するためのより簡潔な方法を提供する、

Collection

インタフェースへの新しいメソッドが導入されました。//docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html[述語]





_:

_

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


Iterator

アプローチとは反対に、https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html#removeIf-java.util.function.Predicate-[

removeIf

]であることに注意することが重要です。

LinkedList



ArrayList

の両方で同様に機能します。

Java 8では、

ArrayList

は、デフォルトの実装(

Iterator

に依存します)をオーバーライドし、異なる戦略を実装します:最初に、要素を反復処理し、__Predicateに一致する要素をマークし、その後、削除(およびシフト)を繰り返します。 )最初の繰り返しでマークされた要素


5 Java 8と

Stream


の紹介

Java 8の新しい主要機能の1つは、https://www.baeldung.com/java-8-streams-introduction[

Stream

](およびhttps://docs.oracle.com/javase/8/docs)の追加です/api/java/util/stream/Collectors.html[

Collectors

])。

ソースから

Stream

を作成する方法はたくさんあります。ただし、

Stream

インスタンスに影響を与えるほとんどの操作はそのソースを変更するのではなく、APIはソースのコピーを作成し、それらに必要な操作を実行することに焦点を当てています。


Stream



Collectors

を使用して、

Predicate

に一致する要素と一致しない要素を検索/フィルタリングする方法を見てみましょう。


5.1.

Stream


を使用した要素の削除


Stream

を使用して要素を削除すること、または

フィルタリングすることは非常に簡単です



Collection

を使用して

Stream

のインスタンスを作成する必要があります。/stream/Stream.html#filter-java.util.function.Predicate-



Predicate

に追加してからhttps://docs.oracle.com/javase/8/docs/api/java/util/stream/に移動します。 Stream.html#collect-java.util.stream.Collector – [

collect

]

Collectorsを使用して結果を表示します。

Collection<String> filteredCollection = names
  .stream()
  .filter(e -> !e.startsWith("A"))
  .collect(Collectors.toList());


Streaming

は以前のアプローチよりも侵襲性が低く、分離を促進し、同じソースから複数のコピーを作成することを可能にします。ただし、アプリケーションによって使用されるメモリも増加することに注意してください。


5.2.

Collectors.partitioningBy



Stream.filter



Collectors

の両方を組み合わせることは非常に便利ですが、** マッチング要素と不一致要素の両方が必要なシナリオに遭遇する可能性があります。 8/docs/api/java/util/stream/Collectors.html#partitioningBy-java.util.function.Predicate-[Collectors.partitioningBy]__:

Map<Boolean, List<String>> classifiedElements = names
    .stream()
    .collect(Collectors.partitioningBy((String e) ->
      !e.startsWith("A")));

String matching = String.join(",",
  classifiedElements.get(true));
String nonMatching = String.join(",",
  classifiedElements.get(false));

このメソッドは、

true



false

の2つのキーのみを含む

Map

を返します。それぞれのキーは、一致する要素と一致しない要素を含むリストを指しています。


6. 結論

この記事では、

Collections

から要素を削除するためのいくつかの方法と、いくつかの注意点について説明しました。


GitHubについて

では、完全なソースコードとすべてのコードスニペットが見つかります。