西海岸より

つらつらざつざつと

Mapを正規表現でフィルターをかける

指定した正規表現に合致するkeyのみ残す関数。メモ。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MapUtil {
	
	public static <V> Map<String, V> filter(Map<String, V> map, String regex) {
		List<String> keyList = new ArrayList<String>(map.keySet());
		for (String key : keyList) {
			if (!key.matches(regex)) {
				map.remove(key);
			}
		}
		return map;
	}
	
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("apple", "red");
		map.put("lemon", "yellow");
		map.put("melon", "green");
		map.put("orange", "orange");

		System.out.println("before ---- ");
		for (String key : map.keySet()) {
			System.out.printf("%s => %s \n", key, map.get(key));
		}
		
		map = MapUtil.filter(map, ".*n$");
		
		System.out.println("after ---- ");
		for (String key : map.keySet()) {
			System.out.printf("%s => %s \n", key, map.get(key));
		}
	}
}
  • 実行結果
before ---- 
orange => orange 
melon => green 
apple => red 
lemon => yellow 
after ---- 
melon => green 
lemon => yellow 

ちなみに、この関数の中で以下のようにするとエラーになるので注意。

	public static <V> Map<String, V> filter(Map<String, V> map, String regex) {
		for (String key : map.keySet()) {
			if (!key.matches(regex)) {
				map.remove(key);
			}
		}
		return map;
	}
  • 実行結果
before ---- 
orange => orange 
melon => green 
apple => red 
lemon => yellow 
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
	at java.util.HashMap$KeyIterator.next(HashMap.java:828)
	at echoserver.MapUtil.filter(MapUtil.java:11)
	at echoserver.MapUtil.main(MapUtil.java:31)

mapのkeyの走査中に、removeを実行することが許されていないため。
keyのcollectionを一度コピーしておけば問題ない。