当前位置: 首页 > 知识库问答 >
问题:

如何映射流到不可变的java类?

蒋芷阳
2023-03-14

考虑一段代码:

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。上下文上下文是不可变的类。因此,put将旧上下文与新的附加值合并,并返回新上下文。

问题是——有没有更简洁的方法可以使用Java8流将HashMap“组合”成不可变的对象?(不适用于上下文类)

注意:我读过关于java stream collect的文章,但这似乎不起作用,因为我必须提供初始的上下文,并在映射后合并几个上下文,但我认为为合并操作重新创建整个上下文太多了。


共有2个答案

边意
2023-03-14

你的问题使我感兴趣。我研究了这个问题。

以下是我的想法:

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);
        }
    }
}

此实用程序方法创建一个新的上下文,其中包含来自初始上下文和提供的映射的条目。

这个解决方案看起来可能仍然不是最优的,因为它创建了一个新的HashMap,initiaCapacity=0,loadFactor=0.75f。事实上,这不是问题,因为ContextN本身是HashMap的一个子类,具有精确的容量和loadFactor=1。中间映射中的数据将被复制到上下文中,然后由GC收集。

注:公用工程类别必须在包Reactor中。util。上下文ContextN是包私有的,因此不能从其他包访问它。

楚俊杰
2023-03-14

您可以使用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实例

如果您编写Context类(或构造函数)的静态方法,该方法接受Map,并且仅为Map的条目创建单个Context实例,则更有意义。但是,我现在注意到您没有编写这个Context类,因此无法更改它。

 类似资料:
  • 我有一个实体,看起来像这样: 输入数据是一个

  • 假设我有一个函数,它接受两个参数并返回一个值,那么可以将映射转换为流中的列表作为非终端操作吗?我能找到的最近的方法是使用地图上的forEach创建实例并将其添加到预定义列表中,然后从该列表中启动一个新流。还是我错过了什么? 经典的“在一长串单词中找出3个最常出现的单词” (现在我想流式处理该地图的入口集)

  • 问题内容: 我有这样的课: 我想为每个MultiDataPoint生成 当然,在多个MultiDataPoints中,“键”可以相同。 因此,给定a ,如何使用Java 8流转换为? 这是我目前在没有流的情况下进行转换的方式: 问题答案: 这是一个有趣的问题,因为它表明有很多不同的方法可以达到相同的结果。下面我展示了三种不同的实现。 集合框架中的默认方法: Java 8向集合类中添加了一些与 St

  • 我有一个不可变对象,它是使用组件映射的Hibernate持久化对象的成员。例如,对应于一个表,该表的字段类型为immutable: 在我的: 这不起作用,因为在运行时HiberNate抱怨没有和的设置器。有没有办法使用不可变对象作为HiberNate持久对象的组件? 跟进:我没有使用注释,而是使用。和都不是。

  • 我有以下代码: 如果我想迭代Map,上面的代码工作得很好。但是现在我有这样的东西。 我想在映射中遍历映射,并获取它的键和值。我想得到key1、value1、key2、value2、key3、value3的值,依此类推。那我该怎么做呢?

  • 我有一个对象出价,它代表一个用户在拍卖中对一个物品的出价。我有一个出价的列表,我想做一个地图,计算在多少(不同的)拍卖的用户作出一个出价。 这是我的看法: 它起作用了,但我觉得我在作弊,因为我流式处理地图的入口集,而不是对初始流进行操作...一定是个更正确的方法,但我想不出来...