2017-02-12 89 views
3

我试图做到这一点下面的代码:与集合转换集合

Map<Node, TreeSet<String>> childrenNodes = new TreeMap<>(getAll()); 

我把下面getAllNodesAndEdges方法的标题:

public Map<Node, Set<String>> getAll() {...} 

我需要转换一个普通地图和设定在它的内部分为TreeMapTreeSet以进行分类打印。但是,第一段代码有编译错误,说"Cannot infer type arguments for TreeMap<>"

什么是解决这个问题的最好方法?

编辑:下面

更多信息在Information.java

public Map<Node, Set<String>> getAll() { 
     return this.all; 
} 

然而,test1.java需要使用代码

Map<Node, HashSet<String>> all = getAll() 

test2.java需要使用的代码

Map<Node, TreeSet<String>> childrenNodes = new TreeMap<Node, TreeSet<String>>(getAll()); 

但两者运行类型不匹配的编译错误

第一:

Type mismatch: cannot convert from Map<Node,Set<String>> to Map<Node,HashSet<String>> 

第二:

The construtor TreeMap<Node,TreeSet<String>>(Map<Node,Set<String>>) is undefined 
+0

您需要的类型参数在'<>'内。它们不能被自动推断,正如错误说 –

+0

或者你可以让'getAll'自行返回一个TreeMap –

+0

@ cricket_007我会怎么做呢? – Michael

回答

2

您必须为新地图的值创建新对象。

Map<Node, TreeSet<String>> converted = new TreeMap<>(); 

for(Entry<Node, Set<String>> entry : childrenNodes.entrySet()){ 
    converted.put(entry.getKey(), new TreeSet<>(entry.getValue())); 
} 
+0

决定,因为这是最适合我的方案中使用此解决方案,旨在感谢 – Michael

0

不能在这样的方式做到这一点。

您可以执行:

1)的变化类型变量childrenNodes的:

Map<Node, Set<String>> childrenNodes = new TreeMap<>(getAll()); 

即不Map<Node, TreeSet<String>>,但Map<Node, Set<String>>

要么

2)使getAll()返回类型

Map<Node, TreeSet<String>> getAll() 

编译器的错误告诉你到底这个东西:它是不可能的推断TreeSet<String>Set<String>。它是大致说与尝试这种类型的任务相同:HashMap<String> foo = getMap();其中getMap()简单地返回Map<String>

+0

我的困境是,我需要childrenNodes成为Map >,因为它需要对已排序的字符串。但是,有时需要将返回值设置为Map >。所以如果没有办法做到这一点,是不是最好创建另一个方法,一个返回TreeSet,一个返回Hash ? – Michael

+0

对,你不能做这样的事情。它就像在说:我想通过'Map '来变量,但有时候会有整数值。其实,你*可以做到这一点,但忘记了类型变量,使用原始类型。或者,使用大多数的基础类型(在你的情况下它是'Set ')。 – Andremoniy

+0

@PatrickParker遗憾,对他们来说,这是邮件处理?对我来说,还是迈克尔? – Andremoniy

0

您不能仅将一种类型的Set(TreeSet,HashSet)强制转换为另一种类型。您需要通过供应商,例如TreeSet::new,通过方法参数。

private final Map<Node, Set<String>> all; 

public <S extends Set<String>, M extends Map<Node, S>> M getAll(Supplier<M> mapFactory, Supplier<S> setFactory) { 
    return all.entrySet().stream() 
     .collect(Collectors.toMap(
      Map.Entry::getKey, 
      e -> e.getValue().stream().collect(Collectors.toCollection(setFactory)), 
      (v1, v2) -> v1, 
      mapFactory)); 
} 

那么你会这样称呼它:

Map<Node, HashSet<String>> test1 = getAll(HashMap::new, HashSet::new); 
Map<Node, TreeSet<String>> test2 = getAll(TreeMap::new, TreeSet::new); 

或者更好的是,使用排序接口而不是实现类的局部变量类型:

Map<Node, Set<String>> test1 = getAll(HashMap::new, HashSet::new); 
SortedMap<Node, SortedSet<String>> test2 = getAll(TreeMap::new, TreeSet::new);