【问题标题】:Learning Java 8 streams学习 Java 8 流
【发布时间】:2017-02-03 12:51:57
【问题描述】:

我有一个现有的代码,我希望转换成 Java8 提供的流:

    for(Person details: modList){

                   if (null != details &&null!=details.getPersonChild()) {
                                  Child mod= details.getPersonChild();

                                  if (mod.isAB() ||
                                          mod.isBC() ||
                                          mod.isCD() ||
                                          mod.idDE() || 
                                          mod.isEF()) {
                                      childeligible = true;
                                                 break;
                                  }
                   }
    }

到目前为止我已经完成了:

return details.stream()
                .filter( p -> null != p && null != p.getPersonChild())
                .map(Person::getPersonChild)
                .anyMatch(mi -> (mod.isAB() || mod.isBC() || mod.isCD() || mod.idDE() || mod.isEF()));

有没有更优化的方法来实现这一点

感谢您的帮助

【问题讨论】:

  • 你能添加一个isABCDEF() 方法吗?
  • 这是一个小的改进,但是一旦您的 Stream 中有子项,您可以使用 .filter(Objects::nonNull) 过滤非空对象。
  • 不该方法不能添加...因为子类不在范围内
  • 您可以使用anyMatch(Child::isBC.or(Child::isCD).or(Child::isDE)),但我不确定这是否更清楚。
  • @KlitosKyriacou,我们需要转换为Predicate,否则它不会编译((Predicate<String>) Child::isAB).or(...)

标签: java collections java-8 java-stream


【解决方案1】:

我可能会这样写

return Details.stream()
            .filter(p -> null != p)
            .map(Person::getPersonChild)
            .filter(pc -> null != pc)
            .anyMatch(pc -> pc.isABCEDF());

isABCDEF 检查所有条件。

不,不能添加该方法

或者您可以添加这个方法,更好地描述它正在检查的内容。

 .anyMatch(pc -> isABCEDF(pc));

如果您不想添加方法,可以按照您的建议进行操作

.anyMatch(c -> c.isAB() || c.isBC() || c.isCD() || c.idDE() ||  c.isEF());

正如@WanderNauta 指出的那样,如果您觉得这更清楚,您还可以使用.filter(Objects::nonNull) 进行空检查。

【讨论】:

  • 或者你将最后一个filteranyMatch 融合:Details.stream().filter(Objects::nonNull).map(Person::getPersonChild).anyMatch(pc -> null != pc && pc.isABCEDF())
  • modList.stream().filter(details->null != details &&null!=details.getPersonChild()) .map(Person::getPersonChild) .anyMatch((Child::isAB || Child::isBC || Child::isCD ||Child.isDE || Child::isEF)); --->>我在写 Child::isAB ||.... 时遇到错误。它说它应该是一个功能接口
  • 确切的错误是这个表达式的目标类型必须是函数接口和anyMatch下的红线((Child::isAB || Child::isBC || Child::isCD ||Child.isDE || 孩子::isEF));
  • 另外它不允许我使用 objects::nonNull 。错误是 Stream 类型中的方法 filter(Predicate super Person>) 不适用于参数(对象: :nonNull)
  • @Hali 你不能使用 ||以这种方式使用谓词,您必须按照 klitos-kyriacou 建议的方式进行操作,但恕我直言,这很丑陋。您的另一个错误是由于代码未编译并且变得混乱。即只有一个错误。
【解决方案2】:

其他解决方案是:

 Details.stream()
    .filter(Objects::nonNull)
    .map(Person::getPersonChild)
    .filter(Objects::nonNull)
    .anyMatch(
      ((Predicate<String>) Child::isAB).
         or(Child::isBC).
         or(Child::isDE).
         or(Child::isEF)
     );

我们在这里使用Predicate.or方法组合了几个Predicates

((Predicate<String>) Child::isAB).or(Child::isBC).or(Child::isDE).or(Child::isEF) 

【讨论】:

    猜你喜欢
    • 2016-06-19
    • 2015-04-02
    • 2014-04-02
    • 2023-01-13
    • 2013-07-28
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 2013-07-20
    相关资源
    最近更新 更多