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

如何避免流中的结果重复?[重复]

文建业
2023-03-14

钱箱类:

public class CashBox {
    private long cashBoxId;
    private BigDecimal totalAmount;
    private long merchantId;

    // all-args constructor
}

商户类:

public class Merchant {
    private long merchantId;
    private BigDecimal totalAmount;

   // all-args constructor
}

输入数据:

List<CashBox> cashBoxes = List.of(
    new CashBox(1, new BigDecimal(1000), 1),
    new CashBox(2, new BigDecimal(2000), 1),
    new CashBox(3, new BigDecimal(3000), 2),
    new CashBox(4, new BigDecimal(500), 2)); 

我的任务

计算每个商家的总金额并返回商家列表

我正在尝试使用Stream API解决这个任务。并编写了以下代码:

List<Merchant> merchant =  cashBoxes.stream()
    .map(merch -> new Merchant(
        merch.getMerchantId(), 
        cashBoxes.stream()
                 .filter(cashBox -> cashBox.getMerchantId() == merch.getMerchantId())
                 .map(CashBox::getTotalAmount)
                 .reduce(BigDecimal.ZERO, BigDecimal::add)))
    .collect(Collectors.toList());

结果

[Merchant{merchantId=1, totalAmount=3000}, Merchant{merchantId=1, totalAmount=3000}, Merchant{merchantId=2, totalAmount=3500}, Merchant{merchantId=2, totalAmount=3500}]

但显然,流返回四个对象,而不是所需的两个对象。我意识到,地图(第二行)为每个cashBoxId创建了四个对象。而且我不知道如何通过商品ID进行过滤,也不知道如何获得没有重复的结果。

共有2个答案

洪琦
2023-03-14

这是使用单个流的“单行”。这个想法是使用Stream::toMap进行分组的优势,使用函数映射值

Collection<Merchant> merchants = cashBoxes.stream()
    .collect(Collectors.toMap(
        CashBox::getMerchantId,
        cashBox -> new Merchant(cashBox.getMerchantId(), cashBox.getTotalAmount()),
        (l, r) -> {
            l.setTotalAmount(l.getTotalAmount().add(r.getTotalAmount()));
            return l;
        }
    ))
    .values();

厉熠彤
2023-03-14

一种方法是使用<code>分组方式。按商户ID分组,然后针对每个组,映射到总金额,并使用相应的收集器进行减少。这将为您提供<code>地图

cashBoxes.stream().collect(Collectors.groupingBy(
    CashBox::getMerchantId, // group by merchant Id
    // for each group...
    Collectors.mapping(// map to total amount
        CashBox::getTotalAmount,
        Collectors.reducing(BigDecimal.ZERO, BigDecimal::add) // sum
    )
)).entrySet().stream()
    .map(x -> new Merchant(x.getKey(), x.getValue())) // map to merchant
    .collect(Collectors.toList());

 类似资料:
  • 创建表(int(10)不为空AUTO_INCREMENT,int(30),varchar(30),varchar(4)不为空,int(2)不为空,主键()); 创建表(varchar(10),主键()); 创建表(int(10),int(30),varchar(30),varchar(4),int(2), varchar(10), varchar(2)not null默认'p'); 分隔符$$ 为

  • 我使用for循环将学生详细信息添加到ArrayList。当我给第二个学生提供详细信息时,它会覆盖第一个数据。螺柱类 将数据添加到ArrayList的主类。 输出:第二个数据[2,2]后的实际输出辊数[1]。预期输出应为卷号: A1姓名: F1 L1性别:男性年龄: 11体育赛事:标枪 报名号:A2姓名:F2 L2性别:女年龄:14体育项目:100米跑 报名号:A3姓名:F3 L3性别:男性年龄:1

  • 我有一个简单的项目,该项目将个人信息提供给数据库(sqlite),现在我想避免插入重复值(按名称),我不能做什么?谢谢你们

  • 如何避免在PHP MYSQLi中插入重复记录?这是我的剧本:

  • 我使用xsl:result-document将输入XML文件拆分为多个子文档。当我的转换在输入文件上的一个大数组上运行时,两个输入“有数据”,因此xsl:result document会尝试创建同一个输出文件两次,从而出错。 理想情况下,我只想创建第二个文档,在文件扩展名之前添加“_2”。我是XSL 2.0的新手,无法想象如何实现这一点。如果有一个全局数组(更像是一个映射),可以保存文档中使用的每

  • 我不断遇到需要通过映射或集合保存状态的解决方案。e、 g.创建一个返回在输入中找到的重复项的方法 我的Java8流解决方案,不幸的是,我正在使用哈希集进行过滤。我理解这并不“恰当”,因为这取决于州。没有州是建议还是硬性规定?这只是运行并行流时的问题吗?有人能推荐一种不使用哈希集的方法吗?