Java8流与嵌套对象

huangapple go评论73阅读模式
英文:

Java8 stream with nested objects

问题

resourceNodes.addAll(gases.stream()
    .map(gas -> gas.getRefinery().unit())
    .collect(Collectors.toList()));

是的,你可以使用流(stream)来简化这段代码,将其压缩成一行。在这个例子中,gases 是一个集合,我们使用 stream() 方法来创建一个流,然后使用 map 操作来将每个 Gas 对象映射为相应的 Unit 对象,最后使用 collect 操作将结果收集到一个新的 ArrayList 中。对于嵌套方法的情况,你可以像上面这样进行链式调用,使用 . 运算符连接多个方法。

英文:

So I'm new to Java8. I've read about streams, but most examples are very basic. I was wondering how it'd be done with nested objects. Here is an example from my code:

for (Gas gas : gases) {
  resourceNodes.add(gas.getRefinery().unit());
}

It seems like I should be able to one-line this with a stream, but I can't quite figure it out. Could someone provide an answer with a stream. Is there a way to use :: syntax with nested methods too?

Edit:
To clarify the example, getRefinery() returns an object of type: UnitInPool, whose method unit() returns an object of type: Unit. resourceNodes is an ArrayList of Unit.

答案1

得分: 3

您提到的::语法是被称为方法引用的内容。

假设resourceNodes在进入for循环之前未被分配(或为空,此时可以删除任何先前的赋值),那么您首先需要对每个Gas执行map操作,将其映射为unit()返回的任何类型,然后将Stream收集到List中:

resourceNodes = gases.stream()
                     .map(Gas::getRefinery)
                     .map(GasRefinery::unit)
                     .collect(Collectors.toList());

否则,如果您的目标只是将内容添加到resourceNodes,那么操作会非常类似:

resourceNodes.addAll(gases.stream()
                          .map(Gas::getRefinery)
                          .map(GasRefinery::unit)
                          .collect(Collectors.toList()));
英文:

The :: syntax that you refer to is what's known as a method reference.


Assuming resourceNodes is unassigned (or empty, in which case you can remove any previous assignment) prior to the for-loop, then you'd want to first map each Gas to whatever type unit() returns, and then collect the Stream to a List:

resourceNodes = gases.stream()
                     .map(Gas::getRefinery)
                     .map(GasRefinery::unit)
                     .collect(Collectors.toList());

Otherwise, if your goal is to simply add to resourceNodes, then it would be very similar:

resourceNodes.addAll(gases.stream()
                          .map(Gas::getRefinery)
                          .map(GasRefinery::unit)
                          .collect(Collectors.toList()));

答案2

得分: 2

你需要提供更多的代码才能得到一个合理的回答,但我猜想你可以通过以下方式获取一系列单位,无论这些单位是什么(以及getRefinery返回的内容):

gases.stream().map(Gas::getRefinery).map(???::unit)

然后你可以使用collect(Collectors.toList())来收集结果,然后只需将收集到的结果作为参数调用resourceNodes.addAll

英文:

You need to provide more code for a reasonable answer, but I'm guessing you can get a stream of units, whetever these are (and whatever getRefinery returns) this way:

gases.stream().map(Gas::getRefinery).map(???::unit)

then you can for example collect the result with collect(Collectors.toList()) and just call resourceNodes.addAll with the collected result as parameter

答案3

得分: 1

resourceNodes = gases.stream().map(gas -> gas.getRefinery().unit()).collect(Collectors.toList());
英文:
resourceNodes = gases.stream().map(gas -> gas.getRefinery().unit()).collect(Collectors.toList());

答案4

得分: 1

如果你只想使用方法引用,你可以使用以下代码:

gases.stream().map(Gas::getRefinery).map(UnitInPool::unit).forEach(resourceNodes::add);
或者
gases.stream().map(Gas::getRefinery).map(UnitInPool::unit).forEach(resourceNodes::add);

否则,使用lambda表达式可能会更好,因为它更短、更易读,并且适用于需要多个参数或执行多个复杂操作的方法。

gases.stream().forEach(g -> resourceNodes.add(g.getRefinery().unit()));

这基本上与你之前的代码相同,但我建议使用for循环。

英文:

If you want only method references, you can use this:

gases.stream().map(Gas::getRefinery).map(UnitInPool::unit).map(resourceNodes::add);
or
gases.stream().map(Gas::getRefinery).map(UnitInPool::unit).forEach(resourceNodes::add);

Otherwise, a lambda would likely be better since it's a lot shorter and more readable, and works, when you have methods that take multiple parameters or need to do multiple complex operations.

gases.stream().forEach(g -> resourceNodes.add(g.getRefinery().unit()));

This is basically the same as your previous code, but I would suggest the for-loop.

答案5

得分: 1

欢迎来到SO社区。我希望以下内容能有所帮助。

List<Unit> resourceNodes = gases.stream() // 打开流
    .map(gas -> gas.getRefinery()) // 转换为UnitInPool
    .filter(unitInPool -> Objects.nonNull(unitInPool)) // 进行空值检查以避免空指针异常
    .map(unip -> unip.getUnit()) // 转换为Unit
    .collect(Collectors.toList()); // 将所有值收集到一个列表中
英文:

Welcome to the SO community. I hope the following helps.

List&lt;Unit&gt; resourceNodes = gases.stream() // open a stream
.map(gas -&gt; gas.getRefinery()) // convert to UnitInPool
.filter(unitInPool -&gt; Objects.nonNull(unitInPool)) // null check to avoid NPE
.map(unip -&gt; unip.getUnit()) // convert to Unit
.collect(Collectors.toList()) // collect all the values in a List

huangapple
  • 本文由 发表于 2020年5月31日 06:32:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/62109429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定