处理Set <Foo>的元素并使用流创建Set <Bar>

tom*_*tom 6 java lambda java-8 java-stream

我有一个Set<String>"hostname:port"对和我想创建一个Set<InetSocketAddress>.我试过它:

Set<InetSocketAddress> ISAAddresses = StrAddresses
    .stream().map(addr -> new InetSocketAddress(
        addr.split(":")[0],
        Integer.parseInt(addr.split(":")[1])));
Run Code Online (Sandbox Code Playgroud)

但这会在IntelliJ中产生以下错误:

不兼容的类型.必需Set<InetSocketAddress>但"map"被推断为Stream<R>:没有类型变量R的实例存在以便Stream<R>符合Set<InetSocketAddress>

我如何使用地图和lambda一定有问题.

Zab*_*uza 10

Stream#map功能并没有返回一个Map.它将流的当前元素转换(映射)到其他元素.因此,它从一个产生Stream<X>一个Stream<Y>使用给定的 变换函数,其需要X和输出Y.

StrAddresses.stream()                           // String
    .map(addr -> new InetSocketAddress(
        addr.split(":")[0],
        Integer.parseInt(addr.split(":")[1]))); // InetSocketAddress
Run Code Online (Sandbox Code Playgroud)

你从a开始,Stream<String>最后得到一个Stream<InetSocketAddress>.

引用其文档:

返回流组成的结果应用给定函数,以该流的元素.


如果要将该流转换为a Set,则需要使用如下Stream#collect方法:

StrAddresses.stream()
    .map(addr -> new InetSocketAddress(
        addr.split(":")[0],
        Integer.parseInt(addr.split(":")[1])))
    .collect(Collectors.toSet());
Run Code Online (Sandbox Code Playgroud)

该实用程序方法Collectors.toSet()返回一个优化良好的收集器Set.如果你明确想要一个,HashSet你可以使用它:

.collect(Collectors.toCollection(HashSet::new));
Run Code Online (Sandbox Code Playgroud)

从其文件:

对此流的元素执行可变减少操作.可变减少是指减少的值是可变结果容器,例如ArrayList[...]


作为一个小注释,您当前每次分割相同的元素两次:

addr.split(":")[0],                     // First
Integer.parseInt(addr.split(":")[1])))  // Second
Run Code Online (Sandbox Code Playgroud)

您可以split通过记忆之前的值来保存该附加程序.在这种情况下,这可以通过使用第二次Stream#map调用来优雅地完成.首先,我们转换Stream<String>Stream<String[]>然后转换为Stream<InetSocketAddress>:

StrAddresses.stream()                                 // String
    .map(addr -> addr.split(":"))                     // String[]
    .map(addrData -> new InetSocketAddress(
        addrData[0], Integer.parseInt(addrData[1])))  // InetSocketAddress
    .collect(Collectors.toSet());
Run Code Online (Sandbox Code Playgroud)

请注意,这Stream#map是一个懒惰的操作.这意味着Java不会改变整个StreamAB一旦你调用该方法.它将一直等到非延迟(完成)操作Stream#collect,然后遍历Stream并应用每个延迟操作 元素.所以,你可以添加尽可能多的Stream#map,只要你喜欢不产生通话额外循环较全Stream.