流操作中的noException

本文介绍了一些简单的编码实践。 没什么好看的。 StackOverflow上也进行了讨论。

您只是将一个庞大而复杂的循环重构为一个更具可读性的流表达式,而忘记了某些方法调用引发了异常。 包含此代码的方法将引发此异常,该异常在方法头中声明。 您不想在此级别上处理此异常。 它在更高级别的调用堆栈上受到关注。 而且您会在代码中遇到令人讨厌的错误,就像钉子下的碎片一样。

假设您要将字符串转换为IP地址。

private static final String[] allowed = {"127.0.0.1", "::1"};

...

Arrays.stream(allowed)
      .map(InetAddress::getByName)
      .collect(Collectors.toSet());

问题是getByName(String host)抛出UnknownHostException 。 这不是RuntimeException因此必须对其进行检查,但是map()方法需要一个Function作为参数,而Function不会引发任何异常。 我们需要一个不会抛出异常的getByName版本(或者我们需要使用一种对异常更me脚的语言)。

Arrays.stream(allowed)
       .map(s -> {
                   try {
                     return InetAddress.getByName(s);
                     } catch (UnknownHostException e) {
                     throw new RuntimeException(e);
                     }
                 }).collect(Collectors.toSet());

这比原始循环更丑陋和混乱。 是否可以尝试/捕获放入实用程序类中的所有内容,并调用一些包装实际调用的la脚静态方法? 是的。 静态导入以下方法:

public interface ExceptionalSupplier<T> {
        T apply() throws Exception;
    }
...
    public static <T> T lame(ExceptionalSupplier<T> z) {
        try {
            return z.apply();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

导入后可以写

Arrays.stream(allowed)
      .map(s -> lame(() -> InetAddress.getByName(s)))
      .collect(Collectors.toSet());

要注意的是,您不能只lame( ... )通话。 您必须将其转换为出色的供应商。 具有与Supplier相同的功能接口,但允许例外。

还是不理想。 (嗯,它是Java,所以您期望什么?)好的。 它是Java,但仍然可以做得更好。 如果不是通过供应商将表达式转换为不引发异常的表达式,我们可以将引发异常的“函数”转换为不引发异常的表达式。 我们需要一个接受异常函数并返回正常函数的方法。 这样,我们可以在代码中保存() ->噪声。 可读性规则。

public interface ExceptionalFunction<T, R> {
        R apply(T r) throws Exception;
    }
...
    public static <T, R> Function<T, R> lame(ExceptionalFunction<T, R> f) {
        return (T r) -> {
            try {
                return f.apply(r);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        };
    }

使用该实用程序,“最终”表达式将是

Collection<InetAddress> allowedAddresses =
        Arrays.stream(allowed)
              .map(lame(InetAddress::getByName))
              .collect(Collectors.toSet());

GIST中的实际实用程序类定义了一个WrapperException扩展了RuntimeException以便您可以在方法中的某个地方捕获异常,例如

public myMethod() throws IOException {
try{
    ... do whatever here we do ...
   } catch (RuntTimeExceptionWrapper.WrapperException we) {
       throw (IOException) we.getCause();
   }

这样,该方法将引发异常,但是如果任何地方还有另一个RuntimeException将引发未捕获。

这只是一个简单,不错的小技巧,可以帮助您跟上Java,它向后兼容,而不是使用现代,简洁的其他语言开始开发,而让您将更多精力放在需要编码的功能上编码技术。

翻译自: https://www.javacodegeeks.com/2017/09/noexception-stream-operation.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值