java - 扩展 HashMap 为未找到的键返回空 HashSet

标签 java hashmap hashset

我想创建一个 HashMap,其中包含 HashSets 作为值,并在找不到键时返回一个空的 HashSet。

public class IsbnHashMap<K,V> extends HashMap<K,V> {
    protected V defaultValue;
    public IsbnHashMap(V defaultValue) {
        this.defaultValue = defaultValue;
    }
    @Override
    public V get(Object k) {
        return containsKey(k) ? super.get(k) : defaultValue;
    }
}

但是我的实现不起作用。

private static IsbnHashMap<String, HashSet<String>> isbnToId = new IsbnHashMap<String, HashSet<String>>();

这将返回“HashSet 无法应用”。如果我尝试改变K,VIsbnHashMap<String, HashSet<String>>我也遇到一些奇怪的错误。我该如何实现这个?

最佳答案

首先应该注意的是,在 Java-8 中您可以使用:

isbnToId.computeIfAbsent(isbn, k -> new HashSet<>()).add(_id);

其次,如果你确实想在以前的 Java 版本中做类似的事情,你最好为此目的创建单独的方法(例如 getOrDefault() ),以免违反约定。第三,您需要创建new HashSet<>()对于每把新 key 。如果返回相同的实例,它将在给定的键之间共享。如果你不希望用户修改它,最好使用不可修改的 Collections.emptySet()作为默认值。这样用户就可以安全地执行 isbnToId.getOrDefault(isbn).contains(_id) ,但正在尝试isbnToId.getOrDefault(isbn).add(_id)会导致异常。如果您想支持修改(Java-8 之前的版本),您可以将元素类传递给构造函数:

public static class MyMap<K, V> extends HashMap<K, V> {
    private Class<?> clazz;

    public MyMap(Class<?> clazz) {
        this.clazz = clazz;
    }

    public V getOrCompute(K key) {
        V v = get(key);
        if(v == null) {
            try {
                v = (V) clazz.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
            put(key, v);
        }
        return v;
    }
}

使用示例:

MyMap<String, Set<String>> map = new MyMap<>(HashSet.class);
map.getOrCompute("a").add("b");
map.getOrCompute("a").add("c");
map.getOrCompute("d").add("e");
System.out.println(map); // {a=[b, c], d=[e]}

这里我们假设使用默认构造函数实例化传递的类是可以的。另一种方法是传递能够生成默认值的工厂接口(interface)。

关于java - 扩展 HashMap 为未找到的键返回空 HashSet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32400847/

相关文章:

java - 如何让一个集合保留包含我在java中指定子字符串的所有字符串?

java - 应为 BEGIN_ARRAY,但在第 1 行第 2 列处为 BEGIN_OBJECT,json语法错误

C# list - 通过比较特定属性消除重复项

java - Double != null 导致 NullPointerException

java - Hibernate 检索多行并存储在对象数组中

java - 访问 java 项目中的 osgi 声明式服务

java - 如何获得hashmap中的两个最大值

java - 如何在 Java 8 中将流转换为 HashMap(而非 Map)

java - 如何从 Java 运行 bash 脚本

java - 根据值对 Map 内的 HashMap 进行排序