Java Lambda嵌套流筛选器(按方法,有异常)

Java Lambda嵌套流筛选器(按方法,有异常),java,lambda,exception-handling,stream,nested,Java,Lambda,Exception Handling,Stream,Nested,我回答了这个问题 代码如下: import java.net.NetworkInterface; import java.net.SocketException; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; 方法 private String[] getHostAddresses() { Set<String> HostA

我回答了这个问题

代码如下:

import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
方法

private String[] getHostAddresses() {
  Set<String> HostAddresses = new HashSet<>();
  try {
    for (NetworkInterface ni : Collections.list(NetworkInterface.getNetworkInterfaces())) {
      if (!ni.isLoopback() && ni.isUp() && ni.getHardwareAddress() != null) {
        for (InterfaceAddress ia : ni.getInterfaceAddresses()) {
          if (ia.getBroadcast() != null) {  //If limited to IPV4
            HostAddresses.add(ia.getAddress().getHostAddress());
          }
        }
      }
    }
  } catch (SocketException e) { }
  return HostAddresses.toArray(new String[0]);
}
但当我改用Try catch时

    try {
      Collections.list(NetworkInterface.getNetworkInterfaces())
          .stream()
          .filter(ni -> {  //incompatible types: bad return type in lambda expression missing return value
            try {
              !ni.isLoopback(); //not a statement cannot find symbol symbol:   method isLoopback() location: variable ni of type T where T is a type-variable: T extends Object declared in interface Stream
            } catch (SocketException ex) {  //exception SocketException is never thrown in body of corresponding try statement
              Logger.getLogger(JPanelServerClient.class.getName()).log(Level.SEVERE, null, ex);
            }
          })
          .filter(ni -> ni.isUp())
          .filter(ni -> ni.getHardwareAddress() != null)
          .flatMap(ni -> ni.getInterfaceAddresses().stream())
          .filter(ia -> ia.getBroadcast() != null)
          .forEach(ia -> HostAddresses.add(ia.getAddress().getHostAddress()));

    } catch (SocketException e) {
      System.out.println(e.getMessage());
    }
根据tip@Jacob-G的说法,这可以解决问题(但他有理由认为“并非所有东西都必须具备功能”)

我如何翻译它(更简单)?
我如何翻译它?

不幸的是,在java流中处理已检查的异常非常糟糕。 您必须创建一个单独的函数,该函数使用谓词(筛选器操作)捕获任何已检查的异常,并将其作为运行时异常重新提交

因为缺乏我的想象力,考虑以下两个你无法控制的功能(想想图书馆或JDK的一部分):


方法1:为两个函数中的每一个编写包装器方法,并在其中处理异常:

boolean isEvenWrapper(int i){
  try{
    return isEven(i);
   } catch (IOException ex){
     throw new UnCheckedIOException(ex);
}
然后您的流看起来像:

Stream.of(1, 2, 3, 4, 5)
        .filter(i -> isEvenWrapper(i)) 
        .filter(i -> isOddWrapper(i))          //compiles and runs.
        .collect(Collectors.toList());
方法2:如果我们有1个或2个过滤函数,方法1很容易,但是如果我们有更多的过滤函数,为每个可丢弃方法编写包装函数就变得单调乏味

我们需要为引发异常的谓词创建一个函数接口

@FunctionalInterface
public interface CheckedPredicate<T> {
    boolean test(T t) throws Throwable;
}
我所描述的方法2功能由
特别是在这门课上

并不是所有的东西都必须是功能性的。要用上一个示例解决您的问题,请更改
!ni.isLoopback()
返回!ni.isLoopback()谓词
必须返回一个
布尔值
。不过,您也需要在异常中返回一个值,或引发异常。为了使代码更接近函数样式代码,您还可以将带有异常的方法包装到帮助函数中,然后在代码的功能部分直接使用帮助函数。
Stream.of(1, 2, 3, 4, 5)
        .filter(i -> isEven(i))// compilation error
        .filter(i -> isOdd(i))// compilation error
        .collect(Collectors.toList());
boolean isEvenWrapper(int i){
  try{
    return isEven(i);
   } catch (IOException ex){
     throw new UnCheckedIOException(ex);
}
Stream.of(1, 2, 3, 4, 5)
        .filter(i -> isEvenWrapper(i)) 
        .filter(i -> isOddWrapper(i))          //compiles and runs.
        .collect(Collectors.toList());
@FunctionalInterface
public interface CheckedPredicate<T> {
    boolean test(T t) throws Throwable;
}
public static <T> Predicate<T> uncheckedPredicate(CheckedPredicate<T> predicate) {
    return t -> {
        try {
            return predicate.test(t);
        } catch (Throwable x) {
            throw new RuntimeException(x);
        }
    };
}
Stream.of(1, 2, 3, 4, 5)
        .filter(uncheckedPredicate(i -> isEven(i)))
        .filter(uncheckedPredicate(i -> isOdd(i)))  //compiles and runs.
        .collect(Collectors.toList());