java - 带有列表和 putIfAbsent 的通用 HashMap

标签 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 类,以便无需转换即可获取 ListMap 的值(List)?

最佳答案

您的类的实例也将是 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;
    }
}

此更改将让您可以像这样使用 map

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
}

关于java - 带有列表和 putIfAbsent 的通用 HashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23546426/

相关文章:

vb.net - 通用扩展方法,List(Of T)

c# - 如何在 C# XML 摘要中显示泛型类型

data-structures - 排序哈希表(map、dictionary)数据结构设计

java - OpenGL图像绘制

java - 在按钮中插入字符数组

java - 画平滑样条java(那个老栗子)

java - Java HashMap使用通配符嵌套泛型

java - 如何维护一个持久化的后台线程?

java - 结合 guava 的 ImmutableList 和 varargs

java - 根据特定键对 HashMap 项进行分组