如何使用Java流合并集合?

huangapple go评论78阅读模式
英文:

How to merge sets using java stream?

问题

You can merge the two sets into a single Set<String> using flatMap() like this:

Set<String> mergedSet = Stream.of(set1, set2)
    .flatMap(Set::stream)
    .collect(Collectors.toSet());

This code flattens the individual sets into a stream of strings and then collects them into a single set.

英文:

I have two Sets like this:

Set&lt;String&gt; set1;
Set&lt;String&gt; set2;

And I want to merge them with

Set&lt;String&gt; s = Stream.of(set1, set2).collect(Collectors.toSet());

but I get the following error:

> no instance(s) of type variable(s) exist so that Set&lt;String&gt; conforms to String
>
>inference variable T has incompatible bounds:
>
> equality constraints: String lower bounds: Set&lt;String&gt;

如何使用Java流合并集合?

How can I convert the Sets to a single Set&lt;String&gt; with flatMap()?
Is there any other solution that can accomplish this operation gracefully?

答案1

得分: 10

如果您坚持使用Stream,您可以使用flatMap将您的Stream&lt;Set&lt;String&gt;&gt;转换为Stream&lt;String&gt;,然后可以将其收集到Set&lt;String&gt;中:

Set&lt;String&gt; s = Stream.of(set1, set2).flatMap(Set::stream).collect(Collectors.toSet());
英文:

If you insist on using Streams, you can use flatMap to convert your Stream&lt;Set&lt;String&gt;&gt; to a Stream&lt;String&gt;, which can be collected into a Set&lt;String&gt;:

Set&lt;String&gt; s = Stream.of(set1, set2).flatMap(Set::stream).collect(Collectors.toSet());

答案2

得分: 2

你可以使用 Stream.concat 来合并两个集合的流并收集成一个集合。

Set<String> s = Stream.concat(set1.stream(), set2.stream()).collect(Collectors.toSet());
英文:

You can use Stream.concat to merge the stream of two sets and collect as set.

Set&lt;String&gt; s = Stream.concat(set1.stream(), set2.stream()).collect(Collectors.toSet());

答案3

得分: 2

Concat

有几种可能的方法 -

***连接***

Set&lt;String&gt; s = Stream.concat(set1.stream(), set2.stream()).collect(Collectors.toSet());

当有超过2个流时会稍微变得复杂因为我们必须编写

Stream.concat(Stream.concat(set1.stream(), set2.stream()), set3.stream())

**连接可能会对深度连接的流造成问题**从文档中可以看出 -
&gt; 当从重复的连接构造流时要小心访问深度连接的流的元素可能会导致深度调用链甚至是StackOverflowException

***减少***

还可以使用Reduce来执行流的连接操作 -

Set&lt;String&gt; s = Stream.of(set1.stream(), set2.stream()).reduce(Stream::concat)
  .orElseGet(Stream::empty).collect(Collectors.toSet());

这里 `Stream.reduce(`) 返回一个可选项这就是为什么调用 `orElseGet` 方法的原因也可以连接多个集合如下所示 -

Stream.of(set1.stream(), set2.stream(), set3.stream()).reduce(Stream::concat).orElseGet(Stream::empty).collect(Collectors.toSet());

与深度连接的流相关的问题也适用于Reduce

***Flatmap***

可以使用Flatmap来获得与以下相同的结果 -

Set&lt;String&gt; s = Stream.of(set1, set2).flatMap(Set::stream).collect(Collectors.toSet());

要连接多个流您可以使用 -

Set&lt;String&gt; s = Stream.of(set1, set2, set3).flatMap(Set::stream).collect(Collectors.toSet());

Flatmap避免了`StackOverflowException`。
英文:

There are couple of approach possible -

Concat

Set&lt;String&gt; s = Stream.concat(set1.stream(), set2.stream()).collect(Collectors.toSet());

It's get slightly ugly for more than 2 streams as we have to write

Stream.concat(Stream.concat(set1.stream(), set2.stream()), set3.stream())

Concat could be a problem for deeply concatenated stream. From documentation -
> Use caution when constructing streams from repeated
> concatenation.Accessing an element of a deeply concatenated stream can
> result in deep call chains, or even StackOverflowException.

Reduce

Reduce can also be used to perform concatenation of stream as -

Set&lt;String&gt; s = Stream.of(set1.stream(), set2.stream()).reduce(Stream::concat)
.orElseGet(Stream::empty).collect(Collectors.toSet());

Here Stream.reduce() returns optional that's the reason for orElseGet method call. It's also possible to contact multiple set as

Stream.of(set1.stream(), set2.stream(), set2.stream()).reduce(Stream::concat).orElseGet(Stream::empty).collect(Collectors.toSet());

Problem associated with deeply contacted stream applies to reduce as well

Flatmap

Flatmap can be used to get same result as -

 Set&lt;String&gt; s = Stream.of(set1, set2).flatMap(Set::stream).collect(Collectors.toSet());

To concat multiple stream you can use -

Set&lt;String&gt; s = Stream.of(set1, set2, set3).flatMap(Set::stream).collect(Collectors.toSet());

flatmap avoids StackOverflowException.

huangapple
  • 本文由 发表于 2020年8月11日 14:20:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/63352543.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定