英文:
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<Unit> resourceNodes = gases.stream() // open a stream
.map(gas -> gas.getRefinery()) // convert to UnitInPool
.filter(unitInPool -> Objects.nonNull(unitInPool)) // null check to avoid NPE
.map(unip -> unip.getUnit()) // convert to Unit
.collect(Collectors.toList()) // collect all the values in a List
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论