web-dev-qa-db-ja.com

セットから要素を削除

セット内の同じ長さのすべての文字列を削除しようとしています。これまでのコードは次のとおりですが、enhanced-for-loopのイテレータからインデックスを取得できません。

public static void removeEvenLength(Set<String> list) {
    for (String s : list) {
        if (s.length() % 2 == 0) {
            list.remove(s);
        }
    }
}
14
f3d0r

Setには、要素のインデックスの概念はありません。セット内の要素には順序がありません。さらに、反復時にIteratorを使用して、コレクションから要素を削除するときに ConcurrentModificationException を回避する必要があります while ループする:

_for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
    String s =  iterator.next();
    if (s.length() % 2 == 0) {
        iterator.remove();
    }       
}
_

Iterator.remove()ではなくSet.remove()を呼び出していることに注意してください。

24
M Anouti

Java 8将来的に誰かを助けるかもしれないソリューションを投稿すると思いました。Java 8 Streamsはfiltercollectfilterメソッドは、ストリームから次のステップに引き継がれる要素をフィルターで除外します。collectメソッドは、要素をいくつかの種類のCollectionまたはMapに結合します。

// The data to filter
final Set<String> strings = 
        new HashSet<>(Arrays.asList("a", "ab", "abc", "abcd"));

// Now, stream it!
final Set<String> odds =
        strings.stream()
               .filter(s -> s.length() % 2 != 0) // keep the odds
               .collect(Collectors.toSet());     // collect to a new set

これは実際には元のコレクションを変更しませんが、奇数長のSetオブジェクトを含む新しいStringを作成します。

Java 8 Streamsの詳細については、この Oracleの優れたチュートリアル または 素晴らしいJavaDocs をチェックしてください。

8
wassgren

Java 8では Collection.removeIf() が導入され、次のことが可能になりました。

set.removeIf(s -> s.length() % 2 == 0)
6
Leonardo Lima

インデックスは必要ありません。ただし、明示的なIteratorは必要です。イテレータには remove() method があり、パラメータがなく、現在のアイテムをコレクションから削除します。

Iterator<String> itr = list.iterator();  // list is a Set<String>!
while (itr.hasNext())
{
    String s = itr.next();
    if (s.length() % 2 == 0) {
        itr.remove();
    }
}
4
rgettman