是否有更优雅/内置的方式来反转Hashmap的键和值?
我目前有以下内容。
private Map<Boolean, List<String>> reverseMap(Map<String, Boolean> permissions) {
List<String> allow = new ArrayList<String>();
List<String> deny = new ArrayList<String>();
Map<Boolean, List<String>> returnvalue = new HashMap<Boolean, List<String>>();
for (Entry<String, Boolean> entry : permissions.entrySet()) {
if(entry.getValue()) {
allow.add(entry.getKey());
} else {
deny.add(entry.getKey());
}
}
returnvalue.put(true, allow);
returnvalue.put(false, deny);
return returnvalue;
}
答案 0 :(得分:6)
您可以考虑使用Guava Multimap
个实现之一。例如:
private Multimap<Boolean, String> reverseMap(Map<String, Boolean> permissions) {
Multimap<Boolean, String> multimap = ArrayListMultimap.create();
for (Map.Entry<String, Boolean> entry : permissions.entrySet()) {
multimap.put(entry.getValue(), entry.getKey());
}
return multimap;
}
或更一般地说:
private static <K, V> Multimap<V, K> reverseMap(Map<K, V> source) {
Multimap<V, K> multimap = ArrayListMultimap.create();
for (Map.Entry<K, V> entry : source.entrySet()) {
multimap.put(entry.getValue(), entry.getKey());
}
return multimap;
}
答案 1 :(得分:1)
我会做类似的事情(但如果你必须经常做这种事情,请考虑Guava),只用List替换List(看起来更加一致)并预先填充reversemap:
private Map<Boolean, Set<String>> reverseMap(Map<String, Boolean> permissions) {
Map<Boolean, Set<String>> returnvalue = new HashMap<Boolean, Set<String>>();
returnvalue.put(Boolean.TRUE, new HashSet<String>());
returnvalue.put(Boolean.FALSE, new HashSet<String>());
for (Entry<String, Boolean> entry : permissions.entrySet())
returnvalue.get(entry.getValue()).add(entry.getKey());
return returnvalue;
}
答案 2 :(得分:1)
首先要注意的是,如果您的值仅为真或假,则您不需要反向映射。如果你有更广泛的价值观,那将是有意义的。
获取具有特定值的条目的一种简单(但不是非常优雅)方式是:
public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
Set<T> keys = new HashSet<T>();
for (Entry<T, E> entry : map.entrySet()) {
if (entry.getValue().equals(value)) {
keys.add(entry.getKey());
}
}
return keys;
}
如果你需要时不时地调用它,你可以看到这不太好。有两个不同的地图(直接和反向)并向两者添加条目是有意义的。您不能使用Bidi地图,因为键和值之间没有1:1的关系。
更新:以下解决方案无效。见评论。
您还可以考虑使用TreeMap并根据值对其进行排序。这样,您可以随时通过调用 map.entrySet()
来获得排序集(首先拒绝条目,然后允许)。缺点是它只有一组。
ValueComparator bvc = new ValueComparator(map);
TreeMap<String,Boolean> sorted_map = new TreeMap(bvc);
class ValueComparator implements Comparator {
Map base;
public ValueComparator(Map base) {
this.base = base;
}
public int compare(Object a, Object b) {
return (Boolean)base.get(a).compareTo((Boolean)base.get(b));
}
}
答案 3 :(得分:0)