Java 无需使用flatMap即可实现flatMap效果

Java 无需使用flatMap即可实现flatMap效果,java,java-stream,Java,Java Stream,我有一个定义开发人员的类 class Developer { private final String name; Set<String> skills = new HashSet<>(); public Developer(final String name, final String... skills) { this.name = name; for (final String skill : skills)

我有一个定义开发人员的类

class Developer {
    private final String name;
    Set<String> skills = new HashSet<>();

    public Developer(final String name, final String... skills) {
        this.name = name;
        for (final String skill : skills) {
            this.skills.add(skill);
        }
    }
}

有没有办法通过
s而不使用
平面图

您可以使用重载版本的
收集器。collect
接受参数
供应商
累加器
组合器

Set<String> skills = developers.stream().map(Developer::getSkills)
                               .collect(HashSet::new, Set::addAll, Set::addAll);
System.out.println("Skills :: " + skills);
编辑 不需要在收集器内部使用线程安全结构,因为它表示:

当并行执行时,可以实例化、填充和合并多个中间结果,以保持可变数据结构的隔离。因此,即使在与非线程安全的数据结构(如ArrayList)并行执行时,并行缩减也不需要额外的同步


flatMap
是一条路要走。很高兴知道你的问题背后的动机

实现相同结果的另一种方法是使用(如其他答案所述)。 您还可以避免使用
映射
,将所有内容放入收集器,如:

Set<String> skills = developers.stream()
    .collect(
        HashSet<String>::new, 
        (acum, dev) -> acum.addAll(dev.skills), 
        Set::addAll
    );
Set skills=developers.stream()
.收集(
HashSet::新,
(acum,dev)->acum.addAll(dev.skills),
集合::addAll
);

您可以这样使用
reduce

Set<String> set = people.stream()
    .map(d -> d.skills)
    .reduce(new HashSet<String>(),
        (map, list) -> { map.addAll(list); return map; });
Set=people.stream()
.map(d->d.skills)
.reduce(新的HashSet(),
(映射,列表)->{map.addAll(列表);返回映射;});

为什么不使用
flatMap
?这是正确的方法。@JohnKugelman我只是想更好地理解map和flatMap之间的区别,我想这个问题的答案会帮助我更好地理解。@John我没有保持任何状态,为什么不安全?你能解释一下我需要使用并发收集吗?因为好的捕获,所以不需要线程安全的结构!我用一个
ConcurrentSkipListSet
@JohnKugelman修改了mi解决方案。请查看我的编辑。这里不需要线程安全的结构。而且,它会为集合中的每个项目生成一个新的
HashSet
。我不介意在haskell上这样做,但在java上应该考虑到这一点。@Logaln在本期中,并行化没有任何优势。
Set<String> skills = developers.stream()
    .collect(
        HashSet<String>::new, 
        (acum, dev) -> acum.addAll(dev.skills), 
        Set::addAll
    );
Set<String> set = people.stream()
    .map(d -> d.skills)
    .reduce(new HashSet<String>(),
        (map, list) -> { map.addAll(list); return map; });