我正在尝试在Java8中使用流.Trying转换for循环以迭代列表(现有代码到流

时间:2017-01-23 10:45:34

标签: java java-8 java-stream

下面是一个for循环,用于迭代请求,从而执行一些逻辑(获取/设置和执行空检查)。

for (Request request : requests) {


        if (request != null && request.getProfileId() != null && 0 < request.getProfileId().longValue()) {


                Detail profileInfo=profileServiceHelper.retreieveProfile(request.getProfileId());

                if (profileInfo != null) {
                    Info info=requestMapper.mapLiloProfileDetail(profileInfo, request);

                    if (info!= null) {
                        profiles.add(info);
                    }
                }
            }
        }

我试图将上面的for循环转换为流: 到目前为止我所做的是(创建一个流,使用过滤器和地图)

requests.stream()
    .filter(request->request != null && request.getProfileId() != null && 0 < request.getProfileId().longValue())
    .map(request -> profileServiceHelper.retreieveProfile(request.getProfileId()));
        //.map((profileDetail,request)->(profileDetail!=null)?requestMapper.mapLiloProfileDetail(profileDetail, request):"");

我需要在流的map方法中传递一个带有两个参数的函数。

请帮忙

3 个答案:

答案 0 :(得分:0)

回到流中携带的先前值始终是个问题。这是一种解决方法,无需调用Stream#filter进行空值检查。

表达式样式空检查的另一个选项是使用新的Java 8 Optional#ofNullableOptional#map静态方法。这甚至允许我们将所有空值检查和映射嵌入forEach,这意味着我们可以返回原始的request

requests.forEach(r -> Optional.ofNullable(r)
        .map(Request::getProfileId).map(id -> profileServiceHelper::retrieveProfile)
        .map(d -> requestMapper.mapLiloProfileDetail(d, r)).ifPresent(profiles::add));

我对事物序列做出的另一个更改是,最后一个语句将getProfileIdprofileServiceHelper.retrieveProfile拆分为两个单独的步骤。这使得它更具可读性,并允许方法参考。

答案 1 :(得分:0)

不幸的是,Stream对象不允许您在任何后续步骤中访问上一步的值 - 流处理中的每个步骤都暗示为“它自己的东西”,理想情况下它也应仅依赖于步骤输入

但回到手头的问题,这是如何解决的:

requests.stream()
  .filter(Objects::nonNull) // you might actually want to review if there can be a null there, looks very awkward if they can
  .filter(request -> request.getProfileId() != null && 0 < request.getProfileId())
  .flatMap(request -> {
     Detail profileInfo = profileServiceHelper.retrieveProfileInfo(request.getProfileId());
     if (profileInfo != null) {
       return Stream.of(requestMapper.mapLiloProfileDetail(profileInfo, request));
     }
     else return Stream.empty();
   })
   .filter(Objects::nonNull)
   .forEach(profiles::add);

但请注意,Java8的lambdas和方法引用并不是最终的结果,并且通常很少需要将完全正常工作的代码转换为流和lambda。

答案 2 :(得分:-1)

试试这个:

    Predicate<Request> filter = req -> req != null && req.getProfileId() != null && 0 < req.getProfileId().longValue() && profileServiceHelper.retreieveProfile(req.getProfileId()) != null && requestMapper.mapLiloProfileDetail(profileInfo, req) != null;
    requests.stream().filter(filter).forEach(req -> profiles.add(requestMapper.mapLiloProfileDetail(profileServiceHelper.retreieveProfile(req.getProfileId()), req)));