我正在尝试编写一个将Map作为字段的类。该字段如下:
Map<String, Collection<String>> courses;
在构造函数中,我必须使用以下形式的字段:
Map<String, Set<String>;
根本不改变字段。 当我尝试使用set初始化字段时出现错误。有人可以告诉我为什么或做什么而不改变原来的领域?
答案 0 :(得分:0)
尽管Set<String>
实际上是Collection<String>
的子类型,但Map<String, Set<String>>
不是Map<String, Collection<String>>
的子类型。事实上,它们是完全不同的类型,你不能将它们分配给另一个。
幸运的是,Map
界面定义了putAll
method,它具有以下签名:
void putAll(Map<? extends K,? extends V> m)
这意味着putAll
方法接受一个映射,其键和值可能分别是其自己的键和值类型的子类型。
因此,在您的示例中,您可以执行以下操作:
public class YourClass {
private final Map<String, Collection<String>> courses = new HashMap<>();
public YourClass(Map<String, Set<String>> courses) {
this.courses.putAll(courses);
}
}
在调用courses
之前,您只需要确保putAll
属性已被实例化。
答案 1 :(得分:0)
我不确定实际问题是什么,但...... 由于运行时类型擦除
,下面的代码正常工作public class SimpleTest {
protected Map<String, ? extends Collection<String>> courses;
public SimpleTest(Map<String,Set<String>> setsMap)
{
courses = setsMap;
}
public static void main(String... args) {
Map<String, ? extends Collection<String>> setMap = new HashMap<String, Set<String>>();
SimpleTest stInstance = new SimpleTest((Map<String, Set<String>>) setMap);
String str1 = "Hi";
String str2 = "Hello";
Set<String> stringSet = new HashSet<>();
stringSet.add(str1);
List<String> stringList = new ArrayList<>();
stringList.add(str2);
((Map<String, Collection<String>>)setMap).put("set1", stringSet);
((Map<String, Collection<String>>)setMap).put("list1", stringList);
System.out.println("set1 class: " + stInstance.courses.get("set1").getClass().getName());
System.out.println("list1 class: " + stInstance.courses.get("list1").getClass().getName());
System.out.println("map content: " + stInstance.courses);
}
}
输出是:
set1 class:java.util.HashSet
list1 class:java.util.ArrayList
map content:{list1=[Hello], set1=[Hi]}
PS。我根本不建议使用这种“技术”。 但作为实验,它很有趣又有趣: - )