编写Java谓词以将列表与另一个列表进行比较

时间:2016-07-28 20:42:22

标签: java lambda java-stream

我正在尝试使用流编写Java lambda表达式来执行以下代码所执行的操作。给定人员列表 DateFilter列表,从人员列表中删除其出生日期与DateFilter列表中某个范围内任何日期匹配的任何人。

    List<Person> people = getPerson();
    List<DateFilter> dateFilters = getDateFilters();        
    List<Person> filteredPersons = new ArrayList<>();

    for(Person p : people){
        boolean isWithinRange = false;
        for(int i = 0; i < dateFilters.size() && !isWithinRange; i++){
            DateFilter dateFilter = dateFilters.get(i);
            if(numOfDaysBetween(p.getBirthDate(),dateFilter.getDate())  < dateFilter.getDiffRange()){
                isWithinRange = true;
            }
        }
        if(!isWithinRange){
            filteredPersons.add(p);
        }
    }

有简化的方法吗?

由于

2 个答案:

答案 0 :(得分:3)

你有两个流操作;一个用于过滤people,另一个用于创建针对所有DateFilter的谓词:

List<Person> matchingPeople = people.stream()
    .filter(p -> dateFilters.stream()
        .anyMatch(df -> 
           numOfDaysBetween(p.getBirthDate(), df.getDate())  < df.getDiffRange()
        )
    )
    .collect(Collectors.toList());

我建议您在DateFilter课程中添加一个方法,以便您可以执行以下操作:

dateFilters.stream().anyMatch(df -> df.includes(p.getBirthDate()))

日期匹配的算法更适合DateFilter类。

答案 1 :(得分:3)

鉴于您的要求:

  

给定人员列表和DateFilter列表,删除任何人   来自人员名单,其出生日期与任何日期相符   DateFilter列表中的范围。

听起来原始people列表的可变性不是问题。考虑到这一点,您可以使用removeIf函数简化代码,该函数也需要Predicate并删除一些样板代码+避免创建新的List

people.removeIf(person -> dateFilters.stream()
    .noneMatch(f -> numOfDaysBetween(person.getBirthDate(), f.getDate()) < f.getDiffRange()));

然后,您的people列表将从与谓词不匹配的任何Person中清除。