Lambda中的控制反转

3
我正在尝试将列表转换为Map的键,并且默认值为null。
然而,我的代码需要通过new关键字创建HashMap,这违反了Spring中控制反转的原则。
请问在Spring中是否有正确的方法来初始化此情况下的映射?
convertStringToList(input).stream().collect(HashMap::new, 
             (map, value) -> map.put(value, null), Map::putAll);

9
你对IOC的理解太死板了。使用new创建HashMap并没有什么问题。 - Henry
2个回答

5

Spring bean自动装配与非Spring配置组件的实例化略有不同。不要害怕使用new关键字和特定的实现。

Map<String, String> newMap = convertStringToList(input).stream().collect(HashMap::new, 
         (map, value) -> map.put(value, null), Map::putAll);

这很好,因为你将Stream收集到Map中,这是一个接口。Spring对流收集使用哪个实现没有影响,因此您必须指定要使用HashMap(而不是例如TreeMap)。如果您这样做...
 Map<String, String> a = b.stream().collect(Map::new, 
         (map, value) -> map.put(value, null), Map::putAll);

在这里,你会看到"Cannot instantiate the type Map" - 它需要实现,而Spring不提供它。


感谢大家和Nikolas的详细解释!只是好奇(也是为了自己学习),为什么不能使用Collections.EMPTY_MAP代替HashMap::new?是因为Collections.EMPTY_MAP是不可变的吗? - newdeveloper1111
1
非常抱歉回复晚了。您需要一个 Supplier<Map<K, V>> (() -> new HashMap<>() 等同于 HashMap::new),因此可以使用 () -> Collections.EMPTY_MAP 或更好的 () -> Collections.emptyMap()。但是,这些都是 Map 的不可变版本,而且方法 Map::putAll 会抛出 UnsupportedOperationException。此外,如果您查看 Collections.emptyMap() 的源代码,您会发现它返回一个私有静态类 Map.EmptyMap 的实例,该实例是一个空的可导航和不可变映射。 - Nikolas Charalambidis

2

对于Spring特定的bean,如repositories、services、configuration classes等,不应使用手动实例化。
但是,手动实例化映射和集合类的实例以实现您的领域逻辑是完全正常的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接