基于可选列表过滤列表

时间:2019-09-03 15:34:08

标签: java java-stream optional

我有一个可选的整数列表, Optional<List<Integer>> id.

我有很多人的名单。 List<People> people.

我有一个采用可选过滤器的过滤器方法。该代码调用存储库以获取人员列表,如果填充了ID的Optional列表,则将根据ID过滤列表中的人员。 People.getId()。

我想使用steams API来避免编辑原始列表。我已经尝试过类似

 return people.stream()
            .filter(p -> !request.getId().orElseGet(ArrayList::new).contains(p.getId()))
            .collect(Collectors.toList());

规格是。

  • 如果没有ID,请全部退回
  • 如果提供了ID-过滤器
  • 如果提供了id但没有匹配项,则返回空列表

当no id匹配时,以上操作将失败,它将返回完整列表。

Optional<List<Integer>> ids = Optional.of(Arrays.asList(1, 2, 3));
List<People> people = datasource...

List<People> filter (Optional < List < Integer >>> ids) {
    List<People> confusion = people.steam(). ?
    return confusion;
}

任何帮助都将不胜感激!

4 个答案:

答案 0 :(得分:2)

仅此而已。

List<People> filter (Optional < List < Integer >>> idsOpt) {
    return 
        idsOpt.map(
            ids ->
                people.stream()
                    .filter(p -> ids.contains(p.getId())
                        .collect(Collectors.toList())
        ).orElse(people);
}

答案 1 :(得分:1)

  

如果没有ID,请全部退回

首先,您只需要一个||条件。如果Optional为空,则Optional.isPresent()将为false,因此在!ids.isPresent()之前添加||将返回{{ 1}}是filter的短路操作,因为||左侧的条件是||,整个条件将是true

  

如果提供了ID-过滤器

第二,需要从您的支票中删除true,并且您需要在!||的右边进行此项检查,以使用{{ 1}}。

  

如果提供了ID但没有匹配项,则返回空列表

第三,如果存在ids.get().contains(p.getId()),则第二张支票将被评估为第一张支票Optional变成ids。如果!ids.isPresent()false中的列表匹配,则检查People对象,如果没有匹配的返回空列表。

所以这三个都可以在下面应用:

id

此外,最好使用Optional而不是List<People> list = people.stream() .filter(p -> !ids.isPresent() || ( ids.get().isEmpty() || ids.get().contains(p.getId()))) .collect(Collectors.toList()); ,然后Optional<Set<Integer>>将是恒定时间操作。

答案 2 :(得分:1)

  

首先,我们消除了用户未输入任何内容的情况。

if (ids == null || !ids.isPresent() || ids.get().isEmpty())
    return getPeopleFromSomewhere();
  

第二,我们处理一个场景,该场景是用户实际上给了我们一些东西

people.stream()
        .filter(p -> ids.get().stream().anyMatch(id -> id.equals(p.getId())))
        .collect(Collectors.toList());
  

最终,如果用户给我们提供了不匹配的ID,我们将返回过滤后的空列表。

最终版本看起来像是类似这些东西。

public List doSomething() {
    Optional<List<Integer>> ids = Optional.of(Arrays.asList(1,2,3));
    List<People> people = getPeopleFromSomewhere();

    if (ids == null || !ids.isPresent() || ids.get().isEmpty())
        return people;

    return people.stream()
            .filter(p -> ids.get().stream().anyMatch(id -> id.equals(p.getId())))
            .collect(Collectors.toList());

}

答案 3 :(得分:1)

有效解决这一问题的方法之一就是

List<People> filteringOperation(Optional<List<Integer>> id, List<People> people) {
    Set<Integer> uniqueIds = id.isPresent() ? new HashSet<>(id.get()) : Collections.emptySet();
    return uniqueIds.isEmpty() ? people : people.stream()
            .filter(p -> uniqueIds.contains(p.getId()))
            .collect(Collectors.toList());
}

以上内容遵循以下规范:

  • 如果没有ID,请全部退回

如果id列表为空,则uniqueIds将为空,并且将返回所有people的现有列表。

  • 如果提供了ID-过滤器

如果id列表中包含值,则这些值将被收集到Set中,并且该集合中包含ID的人将被过滤到结果列表中。

  • 如果提供了id但没有匹配项,则返回空列表

流实现还意味着,如果提供的ID与人员列表中的任何人员都不匹配,则会返回一个空列表。