java.util.stream.Collector的用法

时间:2014-05-28 13:13:06

标签: java lambda java-8

我列出了我机器的所有可用IP。这是一项微不足道的任务,但我正在尝试使用lambda表达式。我这样做了:

ArrayList<String> ips = new ArrayList<>();

StreamUtils.enumerationAsStream(NetworkInterface.getNetworkInterfaces()).filter(networkInterface -> {
    try {
        return networkInterface.isUp();
    } catch (Exception ignore) {
    }           

    return false;
}).forEach(networkInterface -> {
    StreamUtils.enumerationAsStream(networkInterface.getInetAddresses()).filter(inetAddress -> {
        return !inetAddress.isLoopbackAddress() & inetAddress instanceof Inet4Address;
    }).forEach(inetAddress-> {
        ips.add(inetAddress.getHostAddress());
    });
});

有没有办法使用Collector或更好的方式?

StreamUtils#enumerationAsStream是:

public static <T> Stream<T> enumerationAsStream(Enumeration<T> e) {
    return StreamSupport.stream(Spliterators.spliteratorUnknownSize(new Iterator<T>() {
        public T next() {
            return e.nextElement();
        }

        public boolean hasNext() {
            return e.hasMoreElements();
        }
    }, Spliterator.ORDERED), false);
}

2 个答案:

答案 0 :(得分:4)

您应该可以使用Stream.flatMap

  

返回一个流,该流包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果

这样,您就可以将NetworkInterfaces流转换为InetAddresses流,然后您可以对其进行过滤,映射和收集:

networkInterfaceStream.flatMap(networkInterface -> StreamUtils.enumerationAsStream(networkInterface.getInetAddresses()))
        .filter(inetAddress -> { ... })
        .map(inetAddress -> inetAddress.getHostAddress())
        .collect(Collectors.toList());

答案 1 :(得分:3)

在处理可以抛出已检查异常的方法时,使用实现所需处理的实用程序方法很有帮助,例如:重新抛出包含在未经检查的异常中的异常,或者在您的情况下,实现拒绝过滤器行为:

interface ThrowingPredicate<T> {
    boolean test(T t) throws IOException;
}
public static <T> Predicate<T> guard(ThrowingPredicate<T> p) {
    return (x) -> {
        try { return p.test(x); } catch(IOException ex) { return false; }
    };
}

使用此辅助方法,您可以按如下方式执行流操作:

List<String> ips =
    StreamUtils.enumerationAsStream(NetworkInterface.getNetworkInterfaces())
      .filter(guard(NetworkInterface::isUp)
         .and(guard(nif-> !nif.isLoopback())))
      .map(NetworkInterface::getInetAddresses)
      .flatMap(StreamUtils::enumerationAsStream)
      .filter(inetAddress -> inetAddress instanceof Inet4Address)
      .map(InetAddress::getHostAddress)
      .collect(Collectors.toList());

通过研究上述操作,您可能会发现到目前为止您可能错过的多个功能或概念,这些功能或概念可以在将来为您提供帮助。