【问题标题】:Inversion of control in lambdalambda中的控制反转
【发布时间】:2018-12-21 07:28:16
【问题描述】:

我正在尝试将列表转换为 Map 的键,并且默认值为 null。
但是,我的代码需要通过 new 关键字创建 HashMap,这违反了 Spring 中的控制反转原则。

请问在这种情况下 Spring 中是否有任何正确的方法来初始化地图?

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

【问题讨论】:

  • 你对 IOC 的要求太严格了。用 new 创建 HashMap 没有错。

标签: java spring lambda java-stream inversion-of-control


【解决方案1】:

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 的不变性吗?
  • 我很抱歉回答迟了。您需要Supplier&lt;Map&lt;K, V&gt;&gt;() -&gt; new HashMap&lt;&gt;() 等于HashMap::new),因此需要() -&gt; Collections.EMPTY_MAP 或更好的() -&gt; Collections.emptyMap()。但是,这些是 Map 的不可变版本,Map::putAll 方法将抛出 UnsupportedOperationException。此外,如果您查看Collections.emptyMap() 的源代码,您会发现它返回了一个私有静态类Map.EmptyMap 的实例,它是一个空的可导航且不可变的地图。
【解决方案2】:

您不应该对 Spring 特定的 bean 使用手动实例化,例如存储库、服务、配置类等。
但是,手动实例化地图和集合类的实例来实现您的域逻辑是完全正常的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-03
    • 1970-01-01
    • 2010-09-20
    • 2011-07-06
    • 1970-01-01
    • 2020-07-31
    • 2011-04-11
    • 1970-01-01
    相关资源
    最近更新 更多