当前位置: 首页 > 面试题库 >

是否有一种方便的方法来创建谓词来测试字段是否等于给定值?

姜磊
2023-03-14
问题内容

我经常发现自己需要过滤a Stream或使用谓词来检查给定字段是否具有给定值。

比如说我有这个POJO:

public class A {
    private Integer field;

    public A(final Integer field) {
        this.field = field;
    }

    public Integer getField() {
        return field;
    }
}

我想Stream根据的值过滤对象的field

    final Integer someValue = 42;
    Stream.of(new A(42), new A(1729), new A(42), new A(87539319), new A(null))
            .filter(a -> Objects.equals(a.getField(), someValue))
            ...

是否会有一种方便的方法来为该方法生成谓词filter?我注意到有,Predicate.isEqual但不符合需要。

我可以很容易地这样写:

public static <T,R> Predicate<T> isEqual(Function<? super T, ? extends R> f, R value) {
    return v -> Objects.equals(value, f.apply(v));
}

并将其用作:

    Stream.of(new A(42), new A(1729), new A(42), new A(87539319), new A(null))
            .filter(isEqual(A::getField, someValue))
            ...

但我希望尽可能重用JDK中的现有方法。


问题答案:

没有内置的工厂方法,您可以通过查看JFC中的所有用法Predicate并查找“ …中返回谓词的方法”
来轻松检查。除了Predicate自身内部的方法外,只有Pattern.asPredicate()可以返回Predicate

在实现这种工厂方法之前,应该问自己是否真的值得。使您的lambda表达式.filter(a -> Objects.equals(a.getField(), someValue))看起来复杂的原因是,Objects.equals当您可以预测至少一个参数是否为时,就不必使用它null。由于在这里someValue是never
null,因此可以简化表达式:

final Integer someValue = 42;
Stream.of(new A(42), new A(1729), new A(42), new A(87539319), new A(null))
    .filter(a -> someValue.equals(a.getField()))
    …

如果您仍想实现工厂方法并利用已有的方法创造性地赢得价格,则可以使用:

public static <T,R> Predicate<T> isEqual(Function<? super T, ? extends R> f, R value) {
    return f.andThen(Predicate.isEqual(value)::test)::apply;
}

但是,对于生产代码,我宁愿推荐这样的实现:

public static <T,R> Predicate<T> isEqual(Function<? super T, ? extends R> f, R value) {
    return value==null? t -> f.apply(t)==null: t -> value.equals(f.apply(t));
}

这将测试排除在外,该常数是否是null为了简化将在每个测试中执行的操作。因此它仍然不需要Objects.equals。请注意,Predicate.isEqual它的作用类似。



 类似资料:
  • 在空手道中,我希望有一个模式变量,它是响应数据的超集,这样我就可以用相同的模式测试多个请求。 这对于GraphQL应该特别有用,因为请求本身定义了返回的字段。 预期模式: 回答数据: 在本例中,响应返回的所有键。数据应该在架构中,但架构中的任何键都不在响应中。数据应该被忽略。 在空手道中有没有办法做到这一点,或者有没有计划在将来增加这一功能? 编辑:更新了示例,因为唯一遗漏的属性是一个可为空的属性

  • 我可以检查一个帐户是否是一个广告组的成员,但有没有办法告诉一个帐户是否属于一个OU?我想搜索由你而不是由广告组,我不确定如果这是可能的。下面是我如何搜索一个广告组。

  • 问题内容: 具体来说,我正在寻找与/ 等类似的清晰符号。 必须编写一个foreach循环来检查每个对象上方法的返回感觉很臭,所以我希望有一个更好的Java习惯用法。 问题答案: 谓词在Google收藏库中提供。

  • 我的目标是检查LocalDate是否是当前周的一部分。年和月的类似示例startdate.month().eq(localdate.now().getMonthValue());startDate.Year().eq(localDate.Now().getYear()); EX1:10-Jun-2021(当前日)是如果6月7日-6月13日不是当前周的一部分。EX2:6-Jun-2021不是当前周的

  • 有没有Angular2的方法可以做到这一点,或者我只是使用老式的JavaScript?

  • 问题内容: 我正在尝试将长度不定的多个数据列表输出到CSV文件。每个列表应该是输出CSV文件中的一列。有直接的做事方法吗?如果我将每个列表输出为一行,那么我将遍历每个列表并在结束时输出返回值,但是这种方法在按列工作时不起作用。 我曾想过一次逐项检查所有列表并增加一个计数器,但这也会失败,因为有些列表比另一些​​更长。为了解决这个问题,我将不得不在每次迭代时检查计数器是否在每个列表的末尾,这在计算方