问题
Using a Java 8 lambda expression, I'm trying to do something like this.
List<NewObject> objs = ...;
for (OldObject oldObj : oldObjects) {
NewObject obj = oldObj.toNewObject();
obj.setOrange(true);
objs.add(obj);
}
I wrote this code.
oldObjects.stream()
.map(old -> old.toNewObject())
.forEach({new.setOrange("true")})
.collect(Collectors.toList());
This is invalid code because I'm then trying to do .collect()
on what's returned by .forEach()
, but forEach
is void and does not return a list.
How should this be structured?
回答1:
You can use Stream's peek method, which returns the Stream
because it's an intermediate operation. It normally isn't supposed to have a side effect (it's supposed to be "non-interfering"), but in this case, I think the side effect (setOrange(true)
) is intended and is fine.
List<NewObject> newObjects =
oldObjects.stream()
.map(OldObject::toNewObject)
.peek( n -> n.setOrange(true))
.collect(Collectors.toList());
It's about as verbose as your non-streams code, so you can choose which technique to use.
回答2:
You can use peek
.
List<NewObject> list = oldObjects.stream()
.map(OldObject::toNewObject)
.peek(o -> o.setOrange(true))
.collect(Collectors.toList());
Alternatively, you can mutate the elements after forming the list.
List<NewObject> list = oldObjects.stream()
.map(OldObject::toNewObject)
.collect(Collectors.toList());
list.forEach(o -> o.setOrange(true));
来源:https://stackoverflow.com/questions/33557251/java-lambda-expression-mapping-and-then-modifying-a-list