正确使用泛型与集合实例工厂
Proper use of generics with collection instance factory
我正在尝试使用 Apache Commons Collections v4 执行以下操作:
Map<Integer, List<String>> namesPerNumber =
MapUtils.lazyMap(
new HashMap<Integer, List<String>>(),
FactoryUtils.instantiateFactory(ArrayList.class));
namesPerNumber.get(1).add("Mickey");
但是我在调用 lazyMap 时收到以下编译器错误:
The method lazyMap(Map<K,V>, Factory<? extends V>) in the type MapUtils is not applicable for the arguments (HashMap<Integer,List<String&t;>, Factory<ArrayList>)
有什么正确的方法可以使用工厂在地图中生成列表吗?我也试过这个:
Map<Integer, List<String>> namesPerNumber =
MapUtils.lazyMap(
new HashMap<Integer, List<String>>(),
FactoryUtils.<List<String>instantiateFactory(ArrayList.class));
但是我在调用 instantiateFactory 时遇到了这个错误:
The parameterized method <List<String>>instantiateFactory(Class<List<String>>) of type FactoryUtils is not applicable for the arguments (Class<ArrayList>)
我找到的唯一可行的解决方案如下,但我觉得它很丑陋:
Map<Integer, List<String>> namesPerNumber3 =
MapUtils.lazyMap(
new HashMap<Integer, List<String>>(),
new Factory<List<String>>() {
@Override
public List<String> create() {
return new ArrayList<String>();
}
});
感谢任何帮助。
已签名,
失能药
由于类型擦除,class 文字仅支持具体化类型或原始类型,因此 ArrayList.class
表示原始类型 ArrayList
,而不是预期的 ArrayList<String>
。
解决这个问题的一种方法是使用一个未经检查的操作:
@SuppressWarnings("unchecked") Class<ArrayList<String>> type = (Class)ArrayList.class;
Map<Integer, List<String>> namesPerNumber =
MapUtils.lazyMap(
new HashMap<Integer, List<String>>(),
FactoryUtils.instantiateFactory(type));
请注意,@SuppressWarnings("unchecked")
的效果有意限于此处的单个未检查操作。
或者你使用
Map<Integer, List<String>> namesPerNumber =
MapUtils.lazyMap(
new HashMap<Integer, List<String>>(),
FactoryUtils.prototypeFactory(new ArrayList<String>()));
相反。
如果您使用的是 Java 8,最佳选择是
Map<Integer, List<String>> namesPerNumber =
MapUtils.lazyMap(new HashMap<>(), () -> new ArrayList<>());
我正在尝试使用 Apache Commons Collections v4 执行以下操作:
Map<Integer, List<String>> namesPerNumber =
MapUtils.lazyMap(
new HashMap<Integer, List<String>>(),
FactoryUtils.instantiateFactory(ArrayList.class));
namesPerNumber.get(1).add("Mickey");
但是我在调用 lazyMap 时收到以下编译器错误:
The method lazyMap(Map<K,V>, Factory<? extends V>) in the type MapUtils is not applicable for the arguments (HashMap<Integer,List<String&t;>, Factory<ArrayList>)
有什么正确的方法可以使用工厂在地图中生成列表吗?我也试过这个:
Map<Integer, List<String>> namesPerNumber =
MapUtils.lazyMap(
new HashMap<Integer, List<String>>(),
FactoryUtils.<List<String>instantiateFactory(ArrayList.class));
但是我在调用 instantiateFactory 时遇到了这个错误:
The parameterized method <List<String>>instantiateFactory(Class<List<String>>) of type FactoryUtils is not applicable for the arguments (Class<ArrayList>)
我找到的唯一可行的解决方案如下,但我觉得它很丑陋:
Map<Integer, List<String>> namesPerNumber3 =
MapUtils.lazyMap(
new HashMap<Integer, List<String>>(),
new Factory<List<String>>() {
@Override
public List<String> create() {
return new ArrayList<String>();
}
});
感谢任何帮助。
已签名,
失能药
由于类型擦除,class 文字仅支持具体化类型或原始类型,因此 ArrayList.class
表示原始类型 ArrayList
,而不是预期的 ArrayList<String>
。
解决这个问题的一种方法是使用一个未经检查的操作:
@SuppressWarnings("unchecked") Class<ArrayList<String>> type = (Class)ArrayList.class;
Map<Integer, List<String>> namesPerNumber =
MapUtils.lazyMap(
new HashMap<Integer, List<String>>(),
FactoryUtils.instantiateFactory(type));
请注意,@SuppressWarnings("unchecked")
的效果有意限于此处的单个未检查操作。
或者你使用
Map<Integer, List<String>> namesPerNumber =
MapUtils.lazyMap(
new HashMap<Integer, List<String>>(),
FactoryUtils.prototypeFactory(new ArrayList<String>()));
相反。
如果您使用的是 Java 8,最佳选择是
Map<Integer, List<String>> namesPerNumber =
MapUtils.lazyMap(new HashMap<>(), () -> new ArrayList<>());