Java Map <string,set <string =“” >>初始化类型

时间:2018-11-02 08:29:58

标签: 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());
    }
}

编辑

借助被接受的答案,我想出了这个解决方案,它似乎对我来说很好:

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));

2 个答案:

答案 0 :(得分:5)

通用类型不是协变的,因此不能将LinkedHashMap<String, LinkedHashSet<String>>分配给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>());

仍然允许您编程到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));

答案 1 :(得分:1)

然后按如下所示初始化。

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中的泛型类型不是协变逆变