2017-07-28 54 views
1

我在列表中有一个以下过滤器。我需要居住在指定时间范围内的人员,其中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类。

请帮忙吗?

+1

你的问题很难理解,你想要做什么?为了简化你的“Predicate

+0

有两个参数 - 人员和时间。这不是单一的Predicate,而是BiPredicate。 – JiKra

+0

是的,但这两个参数没有相同的范围。你可以完美地创建一个封装一个人的'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)))... 
} 

这是你想要的吗?

+2

谢谢。最后我用了一个类似的静态方法: .filter(person - > peopleTIme.stream()。anyMatch(time - > intersection(person,time))) – JiKra