如何创建临时中间对象以传递给 Stream 中的下一个方法

Posted

技术标签:

【中文标题】如何创建临时中间对象以传递给 Stream 中的下一个方法【英文标题】:How to create temporary intermediate objects to pass to next method in Stream 【发布时间】:2021-07-04 19:43:00 【问题描述】:

我正在继续我的《Modern Java in Action》一书,在那里我又得到了一个查询。

在第 6 章中,作者解释了 groupingBy,我可以通过 Transaction 的 year 属性对交易列表 (List<Transaction>) 进行分组,如下所示

Map<Integer, List<Transaction>> txns = transactions.
                stream().
                collect(groupingBy(Transaction::getYear));

这个Transaction类也有一个类型为Trader (name, city)的成员变量(请看底部的类)

有了这个,我目前正在地图中按年份分组交易。

我的问题是:如果我想获得按年份分组的 Trader 名称和值,我想我必须创建另一个中间类,如下所示

Map<Integer, List<TraderWithValue>>  traderNamesWithAmountByYear = transactions.
                    stream().
                    map(ten -> createObjFromTxn(ten))
                    collect(groupingBy(Transaction::getYear));

所以我想检查是否有一种方法可以避免创建只使用一次的新类TraderWithValue。喜欢动态创建内联代码之类的东西吗?

下面是我的 Transaction 和 Trader 类。

public class Transaction
    private final Trader trader;
    private final int year;
    private final int value;
    // constructors, getters and setters


public class Trader
    private final String name;
    private final String city;
    // constructors, getters and setters

【问题讨论】:

你为什么不想创建一个新类? 我正在寻找可以在许多地方应用的更动态和内联的解决方案。我想如果我开始创建类,会有很多不同方法的值对象 如果您想避免创建/使用新类,那么您共享的第一行代码就是这样做的方法。这意味着在读取过程中检索数据需要付出更多努力,但这是您在新表示与使用现有表示之间进行选择的地方。 嗨@Naman,当我尝试创建新类只是为了表示与现有实体之间的关系时,我觉得我离oops 的基本概念还很远。或者更准确地说,审稿人问我“我的班级在现实世界中指的是什么?”在我的特殊情况下,我觉得我在某个地方受到 java 语言障碍的限制,因为像 javascript 这样的一些现代语言允许我动态创建对象。 【参考方案1】:

如果您正在寻找动态性,您可以为此使用 Tuple&lt;T, U&gt;

但是,您将失去命名变量的舒适度。

两个变量的典型Tuple&lt;T, U&gt;Pair&lt;L, R&gt;

public class Pair<L, R> 
    L left;
    R right;


你可以这样使用它

Map<Integer, Tuple<String, Integer>> traderNamesWithAmountByYear =
    transactions.stream()
                .collect(Collectors.groupingBy(
                    Transaction::getYear,
                    Collectors.mapping(
                        tx -> new Tuple<>(tx.getTrader().getName(), tx.getValue()),
                        Collectors.toList()
                    )
                );

【讨论】:

谢谢让我试试 @NiteeshBhargava 请注意,这会带来对附加库的依赖,否则,您最终会定义另一个类。你如何从结果中读取可能是决定你如何表示它的一个因素,这是问题所缺乏的。 同意@Naman,当可以在我们自己的源代码中完成某些事情时,引入第三方依赖并不是一个好主意。 \n但是我没有清楚地了解我的问题的确切细节,您介意解释一下吗?\n“您如何从结果中读取可能是决定的一个因素你如何表示它,这是问题所缺乏的。” 在我的例子中,源可以是任何东西,例如 DB 调用/API 调用或从本地或网络驱动器加载事务文件。 元组很容易在您的代码中实现,无需依赖。编写代码和测试实际上需要五分钟。

以上是关于如何创建临时中间对象以传递给 Stream 中的下一个方法的主要内容,如果未能解决你的问题,请参考以下文章

传递给构造函数的临时对象的 C++ 寿命

如何选择来自脚本输出的参数并将其传递给 Bamboo 中的下一个脚本或作业?

.NET Core技术研究-中间件的由来和使用

Express学习笔记

Express学习笔记

邮递员:如何从 html 响应中提取值并将其传递给邮递员中的下一个请求