java - 使用 java lambda 将列中具有不同值的值分组

标签 java for-loop lambda

我有这个对象:

QuoteProductDTO 包含三列(名称、值 1、值 2)

    List<QuoteProductDTO> lstQuoteProductDTO = new ArrayList<>();

    lstQuoteProductDTO.add( new QuoteProductDTO("product", 10, 15.5) );
    lstQuoteProductDTO.add( new QuoteProductDTO("product", 05, 2.5) );
    lstQuoteProductDTO.add( new QuoteProductDTO("product", 13, 1.0) );
    lstQuoteProductDTO.add( new QuoteProductDTO("product", 02, 2.0) );

我需要得到一个合并(一个新对象 QuoteProductDTO ):

第一个列名称,我必须获取第一个值“产品”。

第二个(value1)我必须得到最大值13。

第三列我必须得到所有值的总和 20。

最佳答案

这将获取提供的当前数据并生成具有所需数据的新对象。它使用 Java 12+ 的 Collectors.teeing() 方法

鉴于以下数据:

        ArrayList<QuoteProductDTO> lstQuoteProductDTO = new ArrayList<>();
        ArrayList<QuoteProductDTO> nextQuoteProductDTO = new ArrayList<>();

        // empty Quote for Optional handling below.
        QuoteProductDTO emptyQuote = new QuoteProductDTO("EMPTY", -1, -1);

        lstQuoteProductDTO.add(
                new QuoteProductDTO("Product", 10, 15.5));
        lstQuoteProductDTO.add(
                new QuoteProductDTO("Product", 05, 2.5));
        lstQuoteProductDTO.add(
                new QuoteProductDTO("Product", 13, 1.0));
        lstQuoteProductDTO.add(
                new QuoteProductDTO("Product", 02, 2.0));

您可以根据需要将其合并到 QuoteProductDTO 的新实例中。

        QuoteProductDTO prod = lstQuoteProductDTO.stream()
                .collect(Collectors.teeing(
                        Collectors.maxBy(Comparator
                                .comparing(p -> p.value1)),
                        Collectors.summingDouble(
                                p -> p.value2),
                        (a, b) -> new QuoteProductDTO(
                                a.orElse(emptyQuote).name,
                                a.orElse(emptyQuote).value1,
                                b.doubleValue())));

        System.out.println(prod);               

打印

Product, 13, 21.0

您还可以获取不同产品的列表,并将它们放入合并产品列表中。将以下内容添加到新列表,然后将它们添加到主列表。


        nextQuoteProductDTO.add(
                new QuoteProductDTO("Product2", 10, 15.5));
        nextQuoteProductDTO.add(
                new QuoteProductDTO("Product2", 25, 20.5));
        nextQuoteProductDTO.add(
                new QuoteProductDTO("Product2", 13, 1.0));
        nextQuoteProductDTO.add(
                new QuoteProductDTO("Product2", 02, 2.0));

        List<List<QuoteProductDTO>> list = List.of(
                lstQuoteProductDTO, nextQuoteProductDTO);

现在将它们合并到一个对象列表中。

        List<QuoteProductDTO> prods = list.stream().map(lst -> lst.stream()
                .collect(Collectors.teeing(
                        Collectors.maxBy(Comparator
                                .comparing(p -> p.value1)),
                        Collectors.summingDouble(
                                p -> p.value2),
                        (a, b) -> new QuoteProductDTO(
                                a.orElse(emptyQuote).name, 
                                a.orElse(emptyQuote).value1,
                                b.doubleValue()))))
                .collect(Collectors.toList());

         prods.forEach(System.out::println);

打印

Product, 13, 21.0
Product2, 25, 39.0

我创建了一个类来帮助演示这一点。

class QuoteProductDTO {
    public String name;
    public int value1;
    public double value2;

    public QuoteProductDTO(String name, int value1,
            double value2) {
        this.name = name;
        this.value1 = value1;
        this.value2 = value2;
    }

    public String toString() {
        return name + ", " + value1 + ", " + value2;
    }
}



关于java - 使用 java lambda 将列中具有不同值的值分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59738408/

相关文章:

html - 如何在 INPUT 标签上没有 ID 属性的情况下使用 LABEL 标签的 FOR 属性

c++ - 为什么我在运行程序时收到错误 "segmentation fault"?

java - 如何传递参数化 lambda 的构造函数引用?

c# - new Action() 和 lambda 有什么区别?

amazon-web-services - 使用 Lambda 的自定义触发器更新 AWS CloudFormation

java - 同步发送视频到AppSink

java - 独立程序包

java - 使用java中的选择排序按字符串对用户定义的数组进行排序

python - 在 Pandas 中使用 For 循环的数据框

java - 如何根据表格中选定的原始付款记录获取最新的付款状态