はじめに
Mapのキーに大小文字が混在している場合、for文の中でString.toLowerCase()
とMap.put()
を繰り返してキーを小文字化する処理を作ったことがあるが、最近のJavaではStreamを使って簡単にできるらしいと聞いたので試しに書いてみた。
サンプルコード
toLowerKey()
public static Map<String, ?> toLowerKey(Map<String, ?> map) {
return map.entrySet().stream()
.collect(Collectors.toMap(
e -> (e.getKey() == null) ? e.getKey() : e.getKey().toLowerCase(),
e -> e.getValue(),
(oldEntry, newEntry) -> newEntry));
}
解説
-
map.entrySet().stream()
:マップの [キー:値] ごとに処理を行うStreamを取得する -
.collect(Collectors.toMap(...
:Streamの処理結果を新しいMapに保存する -
e -> (e.getKey() == null) ? e.getKey() : e.getKey().toLowerCase()
:キーがnullならそのまま、文字列なら小文字化してキーに設定 -
e -> e.getValue()
:値はそのまま設定 -
(oldEntry,newEntry) -> newEntry
:小文字化した際にキーが重複した場合どちらを残すか 今回は後勝ち
動作結果
Main.java
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) throws Exception {
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("B", 2);
map.put("c", 3);
map.put("d", 4);
map.put(null, 0);
map.put("E", 55);
map.put("e", 5);
map.put("F", 6);
map.put("g", 7);
System.out.println(toLowerKey(map));
}
public static Map<String, ?> toLowerKey(Map<String, ?> map) {
return map.entrySet().stream()
.collect(Collectors.toMap(
e -> (e.getKey() == null) ? e.getKey() : e.getKey().toLowerCase(),
e -> e.getValue(),
(oldEntry, newEntry) -> newEntry));
}
}
Console
{null=0, a=1, b=2, c=3, d=4, e=5, f=6, g=7}
応用
Collectors.toMap(...
の第4引数で、新しく作成するMapのインスタンスを設定できる。
省略した場合は元のMapと同じ型のインスタンスが作成される。
public static LinkedHashMap<String, ?> toLinkedLowerKey(Map<String, ?> map) {
return map.entrySet().stream()
.collect(Collectors.toMap(
e -> (e.getKey() == null) ? e.getKey() : e.getKey().toLowerCase(),
e -> e.getValue(),
(oldEntry, newEntry) -> newEntry,
() -> new LinkedHashMap<>()));
}
public static SortedMap<String, ?> toSortedLowerKey(Map<String, ?> map) {
return map.entrySet().stream()
.filter(e -> e.getKey() != null) //TreeMapのキーにはnullを設定できないため除外
.collect(Collectors.toMap(
e -> e.getKey().toLowerCase(),
e -> e.getValue(),
(oldEntry, newEntry) -> newEntry,
() -> new TreeMap<>()));
}
参考文献