Java Map<String, Set<String>> 初始化类型



我有以下映射:Map<String, Set<String>>,我需要初始化它。这本身不是问题所在。然而,由于我希望Set保持插入顺序,我曾想过用new LinkedHashMap<String, LinkedHashSet<String>>();初始化整个结构,但这迫使我将映射更改为:Map<String, LinkedHashSet<String>>

如果我在初始化时指定了特定类型,为什么我不能使用接口?或者,确保实现嵌套类型的更好方法是什么?


为了更容易理解我为什么要这么做,下面是代码:

private void sortMap(Map<String, Map<Date, Map<String, Long>>> dataMap) {
Map<String, Set<String>> sortedNames = new LinkedHashMap<String, Set<String>>(); // <-- this initialization
for (Map.Entry<String, Map<Date, Map<String, Long>>> entry : dataMap.entrySet()) {
sortedNames.put(entry.getKey(), entry.getValue().get(getCurrentMonthDate()).keySet());
}
}

编辑

在公认答案的帮助下,我想出了这个似乎对我来说很好的解决方案:

Map<String, Set<String>> sortedNames = dataMap.entrySet().stream()
.map(e -> new AbstractMap.SimpleEntry<String, LinkedHashSet<String>>(e.getKey(),
e.getValue().get(getCurrentMonthDate()).keySet().stream()
.collect(Collectors.toCollection(LinkedHashSet<String>::new))))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));

泛型类型不是协变的,因此不能将LinkedHashMap<String, LinkedHashSet<String>>分配给Map<String, Set<String>>

如果需要强制映射值仅为LinkedHashSet,则必须将映射声明为Map<String, LinkedHashSet<String>>

然而,这不应该是必要的,因为您可以用Set<String>:的子类型调用map.put

Map<String, Set<String>> map = new LinkedHashMap<>();       
map.put("key", new LinkedHashSet<String>());

这仍然允许您对Set接口进行编程。


下面是使用流API的代码的更简单版本。

Date curretMonthDate = getCurrentMonthDate();
Map<String, Set<String>> sortedNames = dataMap.entrySet().stream()
.map(e -> new AbstractMap.SimpleEntry<String, LinkedHashSet<String>>(e.getKey(),
e.getValue()
.entrySet()
.stream()
.filter(inner -> inner.getKey().equals(curretMonthDate))
.flatMap(subEntry -> subEntry
.getValue()
.entrySet()
.stream()
.map(Entry::getKey))
.collect(Collectors.toCollection(LinkedHashSet<String>::new))))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));

初始化如下。

Map<String, Set<String>> test = new LinkedHashMap<>();
// initialize to LinkedHashSet<> when putting elements
test.put("key", new LinkedHashSet<>());

不能使用Map<String, Set<String>> test = new LinkedHashMap<String, LinkedHashSet<String>>(),因为LinkedHashMap<String, LinkedHashSet<String>>();不是Map<String, Set<String>>的子类型。

如果不使用通配符,并不是说Java中的泛型类型不是协变逆变

相关内容

最新更新