セット内の同じ長さのすべての文字列を削除しようとしています。これまでのコードは次のとおりですが、enhanced-for-loopのイテレータからインデックスを取得できません。
public static void removeEvenLength(Set<String> list) {
for (String s : list) {
if (s.length() % 2 == 0) {
list.remove(s);
}
}
}
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()
を呼び出していることに注意してください。
Java 8将来的に誰かを助けるかもしれないソリューションを投稿すると思いました。Java 8 Streamsはfilter
やcollect
。filter
メソッドは、ストリームから次のステップに引き継がれる要素をフィルターで除外します。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 をチェックしてください。
Java 8では Collection.removeIf() が導入され、次のことが可能になりました。
set.removeIf(s -> s.length() % 2 == 0)
インデックスは必要ありません。ただし、明示的な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();
}
}