包含Lists和putIfAbsent的通用HashMap

时间:2014-05-08 15:42:12

标签: java generics hashmap concurrenthashmap

在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();
}
  1. 有没有办法通过某些方法扩展HashMap类而不创建子类? (我在C#中看过这个)

  2. 如何修改ListMap类,以便可以在不进行转换的情况下获取ListMaps的值(List)?

2 个答案:

答案 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>> {
...
}