使用Java Streaming API从list.forEach返回列表

时间:2019-03-28 10:51:57

标签: java java-stream

我有一个POJO:

class MyObject {
   private Double a;
   private String b;

   //constructor, getter + setter
}

某些函数正在创建此POJO的列表。 a的某些值可能为null,因此我想将它们替换为0.0。此刻我正在这样做。

public List<MyObject> fetchMyObjects(Predicate predicate) {

     List<MyObject> list = getMyListsOfTheDatabase(predicate);

     list
       .forEach(myObject -> {
           if (myObject.getA() == null) {
               myObject.setA(0.0);
           }
     });

    return list;
}

有没有一种方法可以将forEach集成到返回中?像

 return list
         .stream()
         .someStatement();

这不是关于将null转换为零的最佳位置,而是一个问题,以更好地理解流式API。

6 个答案:

答案 0 :(得分:2)

使用peek功能

  

返回由该流的元素组成的流,另外,当从结果流中消耗元素时,还会对每个元素执行提供的操作。

public List<MyObject> fetchMyObjects(Predicate predicate) {
    return getMyListsOfTheDatabase(predicate)
            .stream()
            .peek(it -> if(it.getA() == null) it.setA(0.0))
            .collect(Collectors.toList());
}

答案 1 :(得分:2)

尽管其他人很乐意回答您提出的问题,但让我退后一步,为您提供您不需要的答案(但也许您想要的答案):您不想去做。流操作应无副作用。您所要的正是流操作,它具有修改进入流的原始对象的副作用。这样的代码风格很差,并且可能会使您之后阅读代码的人感到困惑。

与任何组合流管道相比,您已经拥有的代码可以更好地解决您的问题。

如果可以修改POJO,可能想要的是一个构造器,如果从数据库中检索到a,则将null设置为0,或者是可以从中调用的方法list.forEach

    list.forEach(MyObject::setAToZeroIfNull);
  

这无关紧要,如果这是将null转换为的最佳位置   零,而是一个问题,可以更好地理解流式API。

公平。无论如何,我会让这个答案代表任何突然出现的人。

答案 2 :(得分:1)

您不能使用单个语句返回相同的List实例,但是可以返回包含相同(可能已修改)元素的新List实例:

return list.stream()
           .map(myObject -> {
               if (myObject.getA() == null) {
                   myObject.setA(0.0);
               }
               return myObject;
           })
           .collect(Collectors.toList());

答案 3 :(得分:1)

实际上您应该使用List::replaceAll

list.replaceAll(x -> {
    if(x.getA() == null) x.setA(0.0D);
    return x;
})

答案 4 :(得分:0)

forEach没有返回值,因此您可能正在寻找的是map

return list
    .stream()
    .map(e -> {
        if (e.getA() == null) e.setA(0d);
        return e;
    })
    .whateverElse()...

答案 5 :(得分:0)

以下内容会很好:

list.stream()
    .filter(obj -> obj.getA() == null)
    .forEach(obj -> obj.setA(0.0));
return list;

但是,在您的情况下,仅返回Stream可能更合适(视情况而定):

public Stream<MyObject> fetchMyObjects(Predicate predicate) {
     return getMyListsOfTheDatabase(predicate);
}

public Stream<MyObject> streamMyObjects(List<MyObject> list) {
     return list.stream()
         .peek(obj -> {
             if (obj.getA() == null) {
                 obj.setA(0.0);
             }
         });
}

我个人从未使用过peek,但在这里它会更正值。

关于代码约定,在Java社区中更多的字符串:

  • 缩进:Java采用4而不是C ++的3作为更独立的方法, 并期望减少缩进。值得商but,但是还可以。
  • 对于泛型类型参数,通常使用单个大写字母,例如T, C, S
  • 对于lambda参数,短名称通常是一个字母,因此我使用了obj