🚀
ReverseMap
これは何ですか?
Mapのキーと値を入れ替えます。値が重複していたらどれか一つになります。
情報の欠落しないMap<V, Set<K>>版もありますが使いづらいです。
Collectors.toMap、Collectors.groupingByがnullを扱わないので改良。
ソースコード
import java.util.AbstractMap;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
public class ReverseMap<K, V> extends AbstractMap<V, K> {
private final Map<V, K> map;
public ReverseMap(Map<K, V> map) {
this.map = map.entrySet().stream()
.map(e -> Collections.singletonMap(e.getValue(), e.getKey()))
.collect(HashMap::new, Map::putAll, Map::putAll);
}
@Override
public Set<Entry<V, K>> entrySet() {
return map.entrySet();
}
public static <K, V> Map<V, Set<K>> reverse(Map<K, V> map) {
return map.entrySet().stream()
.collect(Collectors.groupingBy(
e -> Optional.ofNullable(e.getValue()),
Collectors.mapping(Entry::getKey, Collectors.toSet())))
.entrySet().stream()
.collect(Collectors.toMap(e -> e.getKey().orElse(null), Entry::getValue));
}
}
使用例
Map<Integer, String> map = new HashMap<>();
map.put(1, "A");
map.put(2, "B");
map.put(3, "C");
map.put(4, "A");
map.put(5, "B");
map.put(6, "C");
System.out.println(new ReverseMap<>(map));
// => {A=4, B=5, C=6}
System.out.println(ReverseMap.reverse(map));
// => {A=[1, 4], B=[2, 5], C=[3, 6]}
map.put(7, null);
map.put(8, null);
map.put(null, "C");
System.out.println(new ReverseMap<>(map));
// => {null=8, A=4, B=5, C=6}
System.out.println(ReverseMap.reverse(map));
// => {null=[7, 8], A=[1, 4], B=[2, 5], C=[null, 3, 6]}
Discussion