我有一个Map<K, V>
并想将其转换到 Map<K, U>
哪里V
延伸U
。示例:我想从 Map<String, String>
转到至Map<String, Object>
。所有类型的集合都存在这个问题。
This question已经有了一个“hacky”解决方案的答案,并且解释了为什么强制转换泛型类型通常是一个坏主意。但让我们回顾一下 Voo 答案中的示例:
List<String> m = Something;
m.add("Looks good.");
m.add("42");
List<Object> s = (List<Object>)m; // (1) does not compile
List<Object> t = (List)m; // (2) compiles with warnings
Object myObject = s.get(1);
有关此示例的几个问题:
- 为什么这个(1)不能编译?除了 hack (2) 之外,还有其他方法可以使其编译吗?
- 转换
List<String>
时可能会出现什么问题到List<Object>
因为所有字符串都是对象?
我的具体问题:
我有一个Map<Integer, Map<Vector2i, MyClass> > map = ...
其中包含每个级别的 map 。 0 层的 map 类型为 Map<Vector2i, MySubClass> special = ...
。我现在要special
成为 map
的一部分对于键 0,以便访问map
对于键 0 可以视为正常 Map<Vector2i, MyClass>
对象。
该情况是只读的,意味着写入map
和special
分别发生。
最佳答案
What could possibly go wrong when casting a List<String> to a List<Object> since all Strings are objects?
从这个角度看:如果是List<Object>
,一切都可以添加到其中。因此,这可能会出错,例如:
List<Object> t = (List)m; // (2) compiles with warnings
t.add(1235); // it's a List<Object>, so we can add an Integer
for (String s : m) { // m only contains Strings, right?!
System.out.println(s.length());
}
然后你会看到 ClassCastException
一次s
不是String
正如预期的那样。
[附录]
Why does this (1) not compile? Is a way to make it compile other than the hack (2)?
我不确定您的实际问题是什么,所以我只是猜测。但我第一次遇到类似的问题时,是这样的:
/* Just example; functionality does not matter, just that it accepts List<Number> */
public static void printNumbers(List<Number> numbers) {
numbers.forEach(System.out::println);
}
上面的实用方法采用 List<Number>
并打印它们中的每一个。现在您通常有 List<Integer>
, List<Double>
等在您的代码中。但以下代码将进行节点编译:
List<Integer> integers = Arrays.asList(1, 2, 3);
printNumbers(integers);
现在,不要进行疯狂转换(当然,如果您可以控制虚构的实用方法),请执行以下操作:
public static void printNumbers(List<? extends Number> numbers) {
numbers.forEach(System.out::println);
}
现在该方法接受 List
任何类型的Number
s。但是您无法在方法内的列表中添加任何内容(除了 null
),因为实际类型在运行时未知。
这个解释可能有点随意。如果您想了解更多详细信息,请搜索“PECS 规则”(“生产者扩展,消费者 super ”)。同样适用于任何泛型类型,例如 Map
当然,很好。
关于java - 将 Map 转换为具有父类(super class)泛型类型的映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45423601/