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

Xtr*_*mer 1 java interface

我有以下地图: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)

ern*_*t_k 5

通用类型不是协变的,因此您无法将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)