2017-11-04 132 views
1

我回答这个questionLAMBDA由法嵌套流过滤器与异常

这是代码:

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]); 
} 

现在我想使用基于Lamba Stream Java 8进行翻译。 这里我的代码:

try { 

    Collections.list(NetworkInterface.getNetworkInterfaces()) 
     .stream() 
     .filter(ni -> !ni.isLoopback()) //unreported exception SocketException; must be caught or declared to be thrown 
     .filter(ni -> ni.isUp()) //unreported exception SocketException; must be caught or declared to be thrown 
     .filter(ni -> ni.getHardwareAddress() != null) //unreported exception SocketException; must be caught or declared to be thrown 
     .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()); 
} 

但是当我改变使用尝试捕捉...

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()); 
    } 

根据提示@雅各布-G该解决的问题(但他有理由以“不是一切必须是功能性的“)

try { 
    Collections.list(NetworkInterface.getNetworkInterfaces()) 
    .stream() 
    .filter(ni -> { 
    try { 
     return !ni.isLoopback(); 
    } catch (SocketException ex) { 
     System.out.println(ex.getMessage()); 
     return false; 
    } 
    }) 
    .filter(ni -> { 
    try { 
     return ni.isUp(); 
    } catch (SocketException ex) { 
     System.out.println(ex.getMessage()); 
     return false; 
    } 
    }) 
    .filter(ni -> { 
    try { 
     return ni.getHardwareAddress() != null; 
    } catch (SocketException ex) { 
     System.out.println(ex.getMessage()); 
     return false; 
    } 
    }) 
    .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()); 
} 

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

+2

**不马虎不得的做法2的功能功能**。为了解决你最后一个例子的问题,把'!ni.isLoopback();'改成'return!ni.isLoopback();'因为'Predicate'必须返回'boolean'。尽管如此,您还需要在异常中返回一个值,或者抛出异常。 –

+0

为使代码更接近功能样式代码,您还可以将带有异常的方法包装在辅助函数中,然后直接在代码的功能部分中使用辅助函数。 – jrook

回答

0

不幸的是,在Java流中处理已检查的异常很难看。 你必须创建一个单独的函数,它需要谓词(过滤操作)捕获任何检查的异常,重新抛出它作为运行时异常

对于缺乏我的想象力,请考虑以下两个功能,你不能控制库或JDK)的一部分:

boolean isEven(int i) throws IOException { 
    return i % 2 == 0; 
} 

boolean isOdd(int i) throws IOException { 
    return i % 2 == 1; 
} 

Stream.of(1, 2, 3, 4, 5) 
     .filter(i -> isEven(i))// compilation error 
     .filter(i -> isOdd(i))// compilation error 
     .collect(Collectors.toList()); 

方法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是容易的,如果我们有1层或2个过滤器的功能,但如果我们有更多的过滤功能,写一个包装每个可投掷方法的函数变得单调乏味。

我们需要为引发异常的谓词创建一个Functional Interface。

@FunctionalInterface 
public interface CheckedPredicate<T> { 
    boolean test(T t) throws Throwable; 
} 

而另一个Predicate或方法,它采用此CheckedPredicate并安全地评估它。

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()); 

我所描述的,提供由JOOL ,具体由该类Unchecked