收集Set字段的所有值

时间:2017-07-20 08:16:01

标签: java lambda java-8

我有一个集合,其字段类型为Set,带有一些值。我需要创建一个收集所有这些值的新集。

我想知道使用lambda表达式是否可行。

以下是代码行:

Set<String> teacherId = batches.stream()
                               .filter(b -> !CollectionUtils.isEmpty(b.getTeacherIds()))
                               .map(b -> b.getTeacherIds())
                               .collect(Collectors.toSet());

问题是后映射操作,它包含一组字符串。因此,收集操作返回Set<Set<String>>,但我希望将所有值聚合到一个集合中。

4 个答案:

答案 0 :(得分:7)

您需要使用flatMap代替map

Set<String> teacherIds = 
    batches.stream()
           .flatMap(b -> b.getTeacherIds().stream())
           .collect(Collectors.toSet());

请注意,对于空集合,过滤是多余的 - 流式空集合只会导致空流,这不会影响最终结果。 但是,如果getTeacherIds()可以返回null,您仍然需要处理它。使用filter(Objects::nonNull)就足够了,并且可以节省对Apache Commons的依赖。

答案 1 :(得分:2)

您可以使用flatMap获取所有值的Stream,然后收集到Set<String>

Set<String> teacherId = 
    batches.stream()
           .filter(b -> !CollectionUtils.isEmpty(b.getTeacherIds()))
           .flatMap(b -> b.getTeacherIds().stream())
           .collect(Collectors.toSet());

答案 2 :(得分:2)

如果您关心getTeacherIds()不为空,请通过!=明确使用,CollectionUtils.isEmpty只隐藏内容。特别是因为如果getTeacherIds()返回一个空集合 - flatMap处理得很好,那么对我来说根本不需要。

  Set<String> teacherIds = batches
            .stream()
            .filter(x -> x.getTeacherIds() != null)
            .flatMap(x -> x.getTeacherIds().stream())
            .collect(Collectors.toSet());

答案 3 :(得分:1)

  

我想知道使用lambda表达式是否可行。

我抓住了最后一条鱼,:)。

Set<String> teacherIds = batches.stream()//v--- the class of `x`
                                .map(XClass::getTeacherIds)
                                .filter(Objects::nonNull)
                                .flatMap(Collection::stream)
                                .collect(Collectors.toSet());

注意:对不起,我忘了告诉您getTeacherIds是否将内部ID复制到一组新ID,上面的代码适合您。因为它从XClass一次读取ID。