考虑一段代码:
imnport reactor.util.context.Context
public Context addAll (Context ctx, Map.Entry<String, Object> hashMap) {
Context ctxVar = ctx;
for (Map.Entry<String, Object> e : hashMap.entrySet()) {
if (e.getValue() != null) {
ctxVar = ctxVar.put(e.getKey(), e.getValue());
}
}
return ctxVar;
}
reactor.util.context.Context
是不可变的类。因此,put
将旧的上下文与新的附加值合并,并返回 new
上下文。
问题是-是否存在使用Java 8流将HashMap组合为不可变对象的更紧凑的方法? (不仅适用于上下文类)
注意:我已经阅读了有关Java流收集的信息,但似乎不起作用,因为我必须提供初始的Context
并在映射后合并多个上下文,但为合并操作重新创建整个上下文,我认为太多了。
答案 0 :(得分:0)
您可以使用reduce
:
Context ctxVar = hashMap.entrySet()
.stream()
.filter(e -> e.getValue() != null)
.reduce(ctx,
(c, e) -> c.put(e.getKey(), e.getValue()),
(c1, c2) -> c1.putAll(c2));
但是,这确实是浪费的(就像您原来的循环是浪费的一样),因为当仅需要最后一个实例时,它将创建多个Context
实例。
如果您编写static
类(或构造函数)的Context
方法(它接受一个Map
并且仅创建一个Context
实例,那将更有意义) Map
的条目。但是,我现在注意到您没有写这个Context
类,所以您不能更改它。
答案 1 :(得分:0)
您的问题使我感兴趣。我研究了这个主题。
这是我想出的:
package reactor.util.context;
import java.util.Map;
import java.util.Map.Entry;
import static java.util.stream.Collectors.toMap;
public class ContextUtils {
public static Context putAll(Context context, Map map) {
if (map.isEmpty()) {
return context;
} else {
Map contextMap = context.stream()
.filter(e -> e.getValue() != null)
.collect(toMap(Entry::getKey, Entry::getValue));
return new ContextN(contextMap, map);
}
}
}
此实用程序方法创建一个新的Context
,其中包含来自初始上下文和提供的映射的条目。
此解决方案看起来仍然不是最佳解决方案,因为它创建了一个新的HashMap
,其 initiaCapacity = 0 和 loadFactor = 0.75f 。实际上,这不是问题,因为ContextN
本身是HashMap
的子类,具有精确的容量并且 loadFactor = 1 。来自中间映射的数据将被复制到上下文中,然后由GC进行收集。
注意:实用工具类必须位于软件包reactor.util.context
中。 ContextN
是package-private
,因此无法从其他软件包中访问。