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

Collectors.Reducing方法在用作Collectors.PartitionBy的下游时更新相同的标识

梁新觉
2023-03-14

我有一个类似于下面myobject的类。

public class MyObject {
    private String key; // not unique. multiple objects can have the same key.
    private boolean isPermanent;
    private double value1;
    private double value2;
    
    public MyObject merge(MyObject m){
        value1 += m.getValue1();
        value2 += m.getValue2();
        return this;
    }

    // getters, setters and constructors...
}

以下是示例数据:

List<MyObject> objs = new ArrayList<>();

objs.add(new MyObject("1", false, 100, 200));
objs.add(new MyObject("2", false, 300, 100));
objs.add(new MyObject("1", false, 200, 300));

objs.add(new MyObject("3", true, 100, 200));
objs.add(new MyObject("1", true, 500, 100));
objs.add(new MyObject("1", true, 100, 100));

我想基于ispermanentkey组合这些对象,并执行了以下操作:

(注意,我添加了import static java.util.stream.collectors.*,以便在下面的代码中导入groupingbypartitioningbyreducing)

objs.stream()
    .collect(partitioningBy(MyObject::isPermanent,
                            groupingBy(MyObject::getKey,
                                       reducing(new MyObject(), MyObject::merge))));

{false : { 1 : { 300, 500 } } , { 2 : { 300, 100 } }, true : { 1 : { 600, 200 } } , { 3 : { 100, 200 } } }

但我得到的结果是:

{false : { 1 : { 1300, 1000 } } , { 2 : { 1300, 1000 } }, true : { 1 : { 1300, 1000 } } , { 3 : { 1300, 1000 } } }

由于我传递了一个对象作为标识,因此我相信每个组都更新了相同的对象。既然一个lambda不能传递到reduction方法上,那么有没有什么方法可以解决这个问题呢?

共有1个答案

司空俊悟
2023-03-14

可以使用静态合并函数返回新实例

public static MyObject merge(MyObject one,MyObject two) {
    MyObject merged = new MyObject ();
    merged.setValue1(one.getValue1()+two.getValue1());
    merged.setValue2(one.getValue2()+two.getValue2());
    return merged;
}

您必须删除现有的非静态merge方法,以便编译器选择静态方法来代替方法引用。

这样,MyObject::Merge每次都会生成一个新的MyObject实例。

如果不想删除现有方法,如果使用以下lambda表达式替换方法引用,则仍然可以添加statice方法:

(o1,o2)->MyObject.merge(o1,o2)

在不添加静态方法的情况下,可以使用以下lambda表达式替换MyObject::Merge方法引用:

(o1,o2)-> new MyObject().merge(o1).merge(o2)
 类似资料:
  • 问题内容: 有人可以向我解释一下吗: 如果我注释掉最后三行,输出为: 但是,如果我取消最后三行的注释,则输出为: IE。第一个游标已用第二个游标中执行的DML结果进行了更新。 这是预期的行为吗?有什么方法可以预防吗? 我正在运行Python 3.6.3(根据Ubuntu 17.10),以防万一。 问题答案: 如果可能,SQLite会根据需要计算结果行。但这并非总是可能的,因此无法保证。 您永远不要

  • 我正在尝试创建一个刮取下载链接的刮取器,我想使用regex但这对我来说将是一个噩梦,我找到了这个名为BeautifulSoup的库,我正在尝试捕获的子级中的URL,它是 标记,这个 是URL的名称,我不想将所有URL组合在一个列表中,而是使用了dictionary,它是key是名称( )和value是URL的列表,这里的讨论已经足够了。 到目前为止,我只捕获了1个密钥,有没有一个pythonic的

  • 问题内容: 例如,在mysql中更新表时: 表 如果我运行查询 MYSQL会再次写入相同的值还是因为内容相同而忽略它? 这是我提出的问答问题,正如Stack Overflow鼓励的那样,我认为这对于将来有相同问题的其他程序员将是有用的。 问题答案: 正如MYSQL手册中UPDATE语句所暗示的那样, 如果将列设置为其当前值,MySQL会注意到这一点,并且不会对其进行更新。 因此,如果运行此查询,M

  • 本文向大家介绍ThinkPHP添加更新标签的方法,包括了ThinkPHP添加更新标签的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了ThinkPHP添加更新标签的方法。分享给大家供大家参考。具体分析如下: 我们知道,thinkphp的拓展案例blog,只告诉我们怎样去添加标签tag,却没有删除和更新标签的方法,我在前面的《彻底删除thinkphp3.1案例blog标签的方法》为拓展案

  • 我找遍了,但没有找到是否可能。 我有一个MySQL查询: 字段id有一个“唯一索引”,所以不能有两个。现在,如果数据库中已经存在相同的id,我想更新它。但我真的必须再次指定所有这些字段吗,比如: 或: 我已经在插入中指定了所有内容。。。 一个额外的注意事项,我想使用周围的工作来获得ID! 我希望有人能告诉我什么是最有效的方法。

  • 假设我有一个部署网。yaml或PVC。亚马尔。我用一些值更新yaml文件。我该怎么办?再次申请?很抱歉,我搜索并浏览了文档,发现了滚动更新和记录,我相信这对我来说是进一步的学习曲线。 对文件所做的更改 我在没有rbac的情况下创建了efs provisioner,我相信pvc因此处于待定状态。因此,尝试更新YAML以适应变化。