如果存在Optional <>,则抛出异常

mko*_*bit 40 java java-8

假设我想查看流中是否存在对象,如果它不存在,则抛出异常.我可以做的orElseThrow一种方法是使用该方法:

List<String> values = new ArrayList<>();
values.add("one");
//values.add("two");  // exception thrown
values.add("three");
String two = values.stream()
        .filter(s -> s.equals("two"))
        .findAny()
        .orElseThrow(() -> new RuntimeException("not found"));
Run Code Online (Sandbox Code Playgroud)

反过来呢?如果我想在发现任何匹配时抛出异常:

String two = values.stream()
        .filter(s -> s.equals("two"))
        .findAny()
        .ifPresentThrow(() -> new RuntimeException("not found"));
Run Code Online (Sandbox Code Playgroud)

我可以存储Optional,并在isPresent之后进行检查:

Optional<String> two = values.stream()
        .filter(s -> s.equals("two"))
        .findAny();
if (two.isPresent()) {
    throw new RuntimeException("not found");
}
Run Code Online (Sandbox Code Playgroud)

有没有办法实现这种ifPresentThrow行为?试图以这种方式投掷一个不好的做法?

ber*_*rdt 47

ifPresent()如果您的过滤器找到任何内容,您可以使用该调用抛出异常:

    values.stream()
            .filter("two"::equals)
            .findAny()
            .ifPresent(s -> {
                throw new RuntimeException("found");
            });
Run Code Online (Sandbox Code Playgroud)

  • 任何未经检查的异常都可以以这种方式抛出 (3认同)
  • 它不能在 ifPresent 方法中抛出。 (2认同)
  • 是的它可以 - 执行以下操作.`Optional.of(1).ifPresent(s - > {throw new RuntimeException("哦看起来异常");});` (2认同)
  • 只能以这种方式抛出RuntimeException (2认同)
  • 和 Error 的导数 (2认同)

Stu*_*rks 25

既然您只关心是否找到匹配项,而不是实际找到的匹配项,那么您可以使用anyMatch它,而您根本不需要使用它Optional:

if (values.stream().anyMatch(s -> s.equals("two"))) {
    throw new RuntimeException("two was found");
}
Run Code Online (Sandbox Code Playgroud)

  • 或`.anyMatch("two":: equals)` (18认同)
  • @Misha:这是lambda表达式更有效的罕见情况之一,因为它不捕获任何值(因为""两个"是编译时常量).相反,方法引用将始终捕获要在其上调用方法的实例. (8认同)
  • 链接没有评论:http://stackoverflow.com/q/9888508/1441122 :-) (3认同)
  • 我知道@Holger 是对的,但我必须承认@Misha 的`"two"::equals` 是一个非常好的语法。要获得几分之一的性能,很难说不:-) (2认同)
  • @Holger 首先,关于捕获的好点。即使人们已经知道 `str::equals` 具有捕获成本,但令我(以及其他可能的其他人)感到惊讶的是,`"two":equals` 具有捕获成本,即使 `"two"` 是一个编译时常量。但我认为说在这种情况下 lambda 比方法引用更有效是言过其实了;有一些权衡。有通过合成方法的间接寻址,还有该方法的静态足迹和支持它的常量池条目。 (2认同)

asi*_*b87 6

userOptional.ifPresent(user1 -> {throw new AlreadyExistsException("Email already exist");});
Run Code Online (Sandbox Code Playgroud)

这里中括号是强制性的,否则它会显示编译时异常

{throw new AlreadyExistsException("Email already exist");}

public class AlreadyExistsException extends RuntimeException
Run Code Online (Sandbox Code Playgroud)

并且异常类必须扩展运行时异常