2017-07-28 85 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