【问题标题】:Conditioning the filters of a java stream调节 java 流的过滤器
【发布时间】:2019-02-17 09:22:28
【问题描述】:

我正在开发一个过滤器函数,它可以使用许多参数进行过滤,为此我正在使用 Java Streams。这就是我的代码:

public void filter(String cours,String prof,String salle,String group) {

this.appointments().addAll(getTimeTable().getCreneauxsList().stream()
            .filter(e->e.getProf().equalsIgnoreCase(prof) )
            .filter(e->e.getCours().equalsIgnoreCase(cours) )
            .filter(e->e.getSalle().equalsIgnoreCase(salle) )
            .filter(e->e.getGroup().equalsIgnoreCase(group) )
            .collect(Collectors.toList()));
}

我想查看一个或多个参数 cours,salle,prof,group 是否为 null 或其 trim () = "",用它过滤是不值得的,因为结果不是我期望得到的。

但我不知道该怎么做。

【问题讨论】:

  • 你期待什么结果?
  • 在我的集合中,有一些字段为空,所以如果其中一个参数为空,我会得到这些字段,但我想要参数为空或其 trim()="" 所以没有过滤器
  • 类似e -> StringUtils.isBlank(prof) || e.getProf().equalsIgnoreCase(prof)
  • 所以,你想获取字段为空或空字符串的对象列表
  • 否,仅当条件不为空时才应用过滤器

标签: java java-8 java-stream


【解决方案1】:

您可以创建一个方法来在过滤期间处理 null 或空字符串,如下所示:

public static boolean compareNullableString(String str, String filterStr) {

    return (filterStr == null || filterStr.trim().equals("")) ? true : filterStr.equalsIgnoreCase(str);

}

然后像这样修改你的代码:

this.appointments().addAll(getTimeTable().getCreneauxsList().stream()
                .filter(e->compareNullableString(e.getProf,prof) )
                .filter(e->compareNullableString(e.getCours,cours))
                .filter(e->compareNullableString(e.getSalle,salle) )
                .filter(e->compareNullableString(e.getGroup,group) )
                .collect(Collectors.toList()));

【讨论】:

  • 也许只有我一个人,但return filterStr == null || filterStr.trim().isEmpty() || filterStr.equalsIgnoreCase(str); 似乎更具可读性
  • @ernest_k 你是对的。这是个好建议。它将使声明简短且更具可读性。谢谢!!!
【解决方案2】:

你可以使用来自番石榴的Strings.isNullOrEmpty()

boolean isNullOrEmpty = Strings.isNullOrEmpty(e.getProf());

或者有一组来自apache commons的方法:

StringUtils.isBlankStringUtils.isNotBlankStringUtils.isEmptyStringUtils.isNotEmpty

这可能有用:StringUtils.isBlank() vs String.isEmpty()

这是您的情况isNotBlank 正是您正在寻找的:

BiPredicate<String, String> myPredicate = (field, eqString) ->
        StringUtils.isNotBlank(field) && field.equalsIgnoreCase(eqString);

    ...
    .filter(e -> myPredicate.test(e.getProf(), prof))
    .filter(e -> myPredicate.test(e.getCours(), cours))
    .filter(e -> myPredicate.test(e.getSalle(), salle))
    .filter(e -> myPredicate.test(e.getGroup(), group))
    ...

【讨论】:

    【解决方案3】:

    This 答案可以改进。

    方法compareNullableString可以原样。您可以摆脱在forEach 中创建列表和添加元素。过滤也可以提取到Predicate

    List<String> appointments = this.appointments();
    
    Stream<Predicate<Creneauxs>> filterStream = Stream.of(
            e->compareNullableString(e.getProf,prof),
            e->compareNullableString(e.getCours,cours),
            e->compareNullableString(e.getSalle,salle),
            e->compareNullableString(e.getGroup,group)
    );
    Predicate<Creneauxs> filter = filterStream.reduce(Predicate::and).orElse(x->false);
    
    getTimeTable().getCreneauxsList().stream()
      .filter(filter)
      .forEach(appointments::add);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-17
      • 1970-01-01
      • 2010-10-20
      相关资源
      最近更新 更多