我有一段代码用于生成 PDF 文档,它被简化只是为了演示问题。

    PdfPTable table = new PdfPTable(new float[]{ 100.0f });
    List<PdfPCell> cells = new ArrayList<>();

    List<String> labels = Arrays.asList(
            Labels.ITEM_NAME,
            Labels.QUANTITY,
            Labels.PRICE
    );

    for (String label : labels) {
        PdfPCell cell = new PdfPCell(new Phrase(label));
        cells.add(cell);
    }

    for (PdfPCell cell : cells) {
        table.addCell(cell);
    }

我想使用 Java 8 流将其转换为函数式风格。

我知道我可以像这样使用 javascript 减少:
let container = { items: [] };

[1, 2, 3]
        .reduce((container, item) => {
            container.items.push(item);
            return container;
        }, container);

console.log(container); // { items: [ 1, 2, 3 ] }

我试图在 Java 中使用相同的方法,所以我的代码是这样的:
PdfPTable myTable = Stream.of(
            Labels.ITEM_NAME,
            Labels.QUANTITY,
            Labels.PRICE)
            .map(s -> new PdfPCell(new Phrase(s)))
            .reduce(new PdfPTable(new float[]{ 100.0f }), (table, cell) -> {
                table.addCell(cell);
                return table;
            });

但它没有编译,因为在reduce 函数表被识别为单元格,类型不正确匹配。

我试图使用的似乎是累加器功能,这是我的 IDE 显示给我的:
Java 8 流 - 使用带有替代累加器返回类型的 reduce-LMLPHP

从文档:


T result = identity;
 for (T element : this stream)
     result = accumulator.apply(result, element)
 return result;



所有示例都显示了原始算术运算,如计算 sum 并提到这些累加器函数必须是无状态的。我什至不确定我想要做的事情是否正确,请告诉我。

最佳答案

对于可变缩减,您应该使用 collect ,而不是 reduce :

PdfPTable myTable =
    Stream.of(Labels.ITEM_NAME,Labels.QUANTITY,Labels.PRICE)
          .map(s -> new PdfPCell(new Phrase(s)))
          .collect(() -> new PdfPTable(new float[]{ 100.0f }), // supplier
                   (table, cell) -> table.addCell(cell), // accumulator
                   (table1,table2) -> table1.addAllCells(table2.getCells())); // combiner

对于组合器,我对 PdfPTable 类中可能存在或不存在的方法进行了一些假设,但这是总体思路。

关于Java 8 流 - 使用带有替代累加器返回类型的 reduce,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61850427/

10-11 22:28
查看更多