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.
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()));
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
resourceNodes = gases.stream().map(gas -> gas.getRefinery().unit()).collect(Collectors.toList());
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.
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.