Java lambda expression — mapping and then modifying a list?

浪尽此生 提交于 2019-12-18 07:02:02

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!