for、whileなど、反復文の中でHashMapを巡回しながら要素を削除する方法を紹介します。
1. ConcurrentModificationException
繰り返し文を使用して HashMap を巡回しながら、特定の条件の要素を削除する場合があります。
問題は、 HashMap 巡回中、要素を削除すると ConcurrentModificationException が発生することがあります。
たとえば、以下のように HashMap を巡回しながら HashMap.remove()
で要素を削除すると Exception が発生することがあります。
したがって、以下のように削除しないでください。
import java.util.HashMap;
public class Example {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("apple", 100);
map.put("kiwi", 200);
map.put("banana", 300);
map.put("grape", 400);
for (String key: map.keySet()) {
if (key.startsWith("k")) {
map.remove(key);
}
}
System.out.println(map);
}
}
Output:
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1597)
at java.base/java.util.HashMap$KeyIterator.next(HashMap.java:1620)
at Example.main(Example.java:13)
2. Iteratorで巡回中の要素を削除する
Iterator を使って巡回しながら Iterator.remove()
で要素を削除することは Exception が発生しません。
以下のように特定の要素を削除するように実装できます。
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class Example {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("apple", 100);
map.put("kiwi", 200);
map.put("banana", 300);
map.put("grape", 400);
Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator();
while (it.hasNext()) {
if (it.next().getKey().startsWith("k")){
it.remove();
}
}
System.out.println(map);
}
}
Output:
{banana=300, apple=100, grape=400}
3. Listを使用してHashMap要素を削除する
HashMap 巡回中に削除する要素をリストに保存し、List を再度巡回しながら HashMap の要素を削除できます。 HashMap 巡回中の要素を削除するものではないため、ConcurrentModificationException は発生しません。
以下のように要素を削除できます。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class Example {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("apple", 100);
map.put("kiwi", 200);
map.put("banana", 300);
map.put("grape", 400);
List<String> willRemove = new ArrayList<>();
for (String key: map.keySet()) {
if (key.startsWith("k")) {
willRemove.add(key);
}
}
for (String str : willRemove) {
map.remove(str);
}
System.out.println(map);
}
}
Output:
{banana=300, apple=100, grape=400}
4. removeIf() で巡回中の要素を削除する
removeIf()
は引数として 1 つの引数と戻り値を持つ関数型インタフェースを受け取ります。この関数である要素に対して true を返すと、その要素は削除されます。
removeIf()
も ConcurrentModificationException を発生させないので、この方法で要素を削除できます。
以下のように特定の要素を削除するように実装できます。
import java.util.HashMap;
public class Example {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("apple", 100);
map.put("kiwi", 200);
map.put("banana", 300);
map.put("grape", 400);
map.entrySet().removeIf(entry -> entry.getKey().startsWith("k"));
System.out.println(map);
}
}
Output:
{banana=300, apple=100, grape=400}
4.1 HashMap.keySet().removeIf()
entrySet()
の代わりにkeySet()
を使って要素を削除することもできます。
keySet()
は HashMap のすべての key に対する collection なので、 key だけを巡回できます。
import java.util.HashMap;
public class Example {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("apple", 100);
map.put("kiwi", 200);
map.put("banana", 300);
map.put("grape", 400);
map.keySet().removeIf(key -> key.startsWith("k"));
System.out.println(map);
}
}
Output:
{banana=300, apple=100, grape=400}
4.2 HashMap.values().removeIf()
values()
は HashMap の value を collection として返し、 removeIf()
で特定の value の要素を削除できます。
import java.util.HashMap;
public class Example {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("apple", 100);
map.put("kiwi", 200);
map.put("banana", 300);
map.put("grape", 400);
map.values().removeIf(val -> val == 200);
System.out.println(map);
}
}
Output:
{banana=300, apple=100, grape=400}
Related Posts
- Java - BufferedReaderでファイルを読む
- Java - BufferedWriterでファイルを書き込む
- Java - BigIntegerの範囲、比較、演算、キャスト
- Java charAt()関数を学ぶ
- Java contains()で文字(大文字と小文字のX)を含める
- Java - Set(HashSet)を配列に変換する
- Java - 文字列の最初の文字、最後の文字を確認する
- Java - 文字列を1文字ずつ切り捨てる
- Java - 文字列の単語数を取得する
- Java - 1秒ごとに繰り返し実行
- Java - 配列をSet(HashSet)に変換する
- Java - 複数のSet(HashSet)を組み合わせる
- Java - コマンドライン引数の入力を受け取る
- Java - リスト逆順に巡回、3つの方法
- Java - 特定の条件でリストをフィルタリングする3つの方法
- Java - HashMapすべての要素の合計、平均計算
- Java - 特定の条件でHashMapをフィルタリングする
- Java - シングルトンパターンの実装
- Java - 数字の左側にゼロを埋める
- Java - String配列の初期化方法
- Java - ソートされた順序で Map(HashMap) 巡回