【问题标题】:Create a separate predicate创建一个单独的谓词
【发布时间】:2017-07-28 14:41:07
【问题描述】:

我的列表中有以下过滤器。我需要生活在指定时间范围内的人,其中两个列表中的 validTo 都是可选的。如您所见,它有点复杂,因为还有其他过滤器,我需要通过将谓词移动到变量来使其变得简单。

people.stream()
            .filter(person -> peopleTime.stream().anyMatch(time ->
                    (!person.getValidTo().isPresent() || time.getValidFrom().isBefore(person.getValidTo().get()) || time.getValidFrom().isEqual(person.getValidTo().get()))
                            && (!time.getValidTo().isPresent() || time.getValidTo().get().isAfter(person.getValidFrom()) || time.getValidTo().get().isEqual(person.getValidFrom()))))

我尝试创建一些 BiPredicate 并使用它,但 anyMatch 需要单个谓词。 Person 类扩展了 Time 类。

有什么帮助吗?

【问题讨论】:

  • 你的问题很难理解,你想做什么?将您的Predicate<Time> 简化为单一方法?什么阻碍了你?
  • 有两个参数——Person和Time。它不是单谓词,而是双谓词。
  • 是的,但这两个参数的范围不同。你可以完美地创建一个 Predicate<Time> 封装一个人。
  • 究竟如何封装?

标签: lambda java-8 predicate


【解决方案1】:

据我了解,你基本上有:

public abstract static class MyDate {
    public abstract boolean isBefore(MyDate other);
    public abstract boolean isAfter(MyDate other);
    public abstract boolean isEqual(MyDate other);
}
public static abstract class Time {
    public abstract Optional<MyDate> getValidTo();
    public abstract Optional<MyDate> getValidFrom();
}

public static abstract class Person extends Time {
}

(好吧,我现在要离开实现了)。

如果你创建以下类:

public static class TimePersonPredicate implements Predicate<Time> {

    private final Person person;
    public TimePersonPredicate(Person person) {
        this.person = person;
    }
    @Override
    public boolean test(Time time) {
        return (!person.getValidTo().isPresent() || time.getValidFrom().get().isBefore(person.getValidTo().get()) || time.getValidFrom().get().isEqual(person.getValidTo().get()))
                && (!time.getValidTo().isPresent() || time.getValidTo().get().isAfter(person.getValidFrom().get()) || time.getValidTo().get().isEqual(person.getValidFrom().get()));
    }

}

你可以像这样缩短你的过滤线:

public static void main(String[] args) {
    List<Person> people = new ArrayList<>();
    List<Time> peopleTime = new ArrayList<>();
    people.stream()
        .filter(person -> peopleTime.stream().anyMatch(new TimePersonPredicate(person) ))...
}

这就是你想要的吗?

【讨论】:

  • 谢谢。最后我使用了一个类似的静态方法: .filter(person -> peopleTIme.stream().anyMatch(time -> intersection(person, time)))
猜你喜欢
  • 1970-01-01
  • 2017-10-27
  • 1970-01-01
  • 1970-01-01
  • 2013-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多