我有以下地图: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());
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
在接受的答案的帮助下,我提出了这个解决方案似乎对我来说很好用:
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));
Run Code Online (Sandbox Code Playgroud)
通用类型不是协变的,因此您无法将a分配LinkedHashMap<String, LinkedHashSet<String>>给a Map<String, Set<String>>.
如果您只需要强制映射值LinkedHashSet,则必须将映射声明为Map<String, LinkedHashSet<String>>.
但是,这不应该是必要的,因为您可以map.put使用以下子类型调用Set<String>:
Map<String, Set<String>> map = new LinkedHashMap<>();
map.put("key", new LinkedHashSet<String>());
Run Code Online (Sandbox Code Playgroud)
这仍然允许您编程到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));
Run Code Online (Sandbox Code Playgroud)