在Java中,我想将一个getOrAdd方法添加到常规映射中,就像在ConcurrentHashMap上的putIfAbsent一样。
此外,对于某个键,我想存储一个项目列表。这是我的尝试:
public class ListMap<K, V> extends HashMap<K, V> {
private HashMap<K, List<V>> map;
public ListMap() {
map = new HashMap<K, List<V>>();
}
public List<V> getOrAdd(K key) {
if (map.containsKey(key)) {
return map.get(key);
} else {
List<V> l = new ArrayList<V>();
map.put(key, l);
return l;
}
}
}
但是,如果有人想迭代ListMap,他需要明确地转换值。
ListMap<Integer, MyClass> listMap = new ListMap<Integer, MyClass>();
for (Map.Entry<Integer, MyClass> entry : listMap.entrySet()) {
List<MyClass> val = (List<MyClass>) entry.getValue();
}
有没有办法通过某些方法扩展HashMap类而不创建子类? (我在C#中看过这个)
如何修改ListMap类,以便可以在不进行转换的情况下获取ListMaps的值(List)?
答案 0 :(得分:2)
您的课程实例也将是HashMap,因此您不需要,甚至不应该添加另一个字段来支持getOrAdd
方法,因为其他继承和未覆盖的方法将不会引用map
字段,但引用this
实例。
所以不要添加单独的字段
private HashMap<K, List<V>> map;
将ListMap
的扩展类型更改为
public class ListMap<K, V> extends HashMap<K, List<V>>
^^^^^^^
并将您的getOrAdd
方法更改为不使用map
字段,但this
public List<V> getOrAdd(K key) {
if (containsKey(key)) {
return get(key);
} else {
List<V> l = new ArrayList<V>();
put(key, l);
return l;
}
}
此更改可让您使用地图
ListMap<Integer, String> listMap = new ListMap<Integer, String>();
for (Map.Entry<Integer, List<String>> entry : listMap.entrySet()) {
List<String> val = entry.getValue();//NO CASTING NEEDED
}
答案 1 :(得分:1)
您可以像这样延长HashMap
:
public class ListMap<K, V> extends HashMap<K, List<V>> {
...
}