Java 8 中“If/Throw, Else/Return”逻辑的简写?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26499904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 02:38:38  来源:igfitidea点击:

Shorthand for "If/Throw, Else/Return" logic in Java 8?

javajava-8

提问by Sam Berry

Is there a shorter syntax to if/throw else/return in Java 8? java.util.Optionalprovides a means to accomplish this in one statement, but it requires creating an Optionalinstance with every call that has a non-null reference.

在 Java 8 中是否有更短的 if/throw else/return 语法?java.util.Optional提供了一种在一个语句中完成此操作的方法,但它需要Optional为每个具有非空引用的调用创建一个实例。

Can this be accomplished in a single statement?

这可以在单个语句中完成吗?

public static MyEnum fromString(String value) {
    MyEnum result = enumMap.get(value);
    if (result == null)
        throw new IllegalArgumentException("Unsupported value: " + value);
    return result;
}

Optional Example (bad, requires Optional instance every time)

可选示例(不好,每次都需要可选实例)

public static MyEnum fromString(String value) {
    return Optional.ofNullable(enumMap.get(value)).orElseThrow(
        () -> new IllegalArgumentException("Unsupported value: " + value));
}

采纳答案by Holger

The impact of a temporary Optionalinstance is negligible. Usually the JVM will detect its temporary nature and optimize away the instance. Even if the temporary instance creation is not optimized away, the impact of one single temporary object on the memory management is ridiculously low.

临时Optional实例的影响可以忽略不计。通常 JVM 会检测它的临时性质并优化掉实例。即使临时实例的创建没有被优化掉,单个临时对象对内存管理的影响也是低得离谱的。

However, if the map is mutable, you can use the following trick:

但是,如果地图是可变的,您可以使用以下技巧:

public static MyEnum fromString(String value) {
    return enumMap.computeIfAbsent(value, v -> {
        throw new IllegalArgumentException("Unsupported value: " + v); });
}

Note that the Mapis not modified by this code but still must be mutable as an immutable map might throw an UnsupportedOperationexception for the attempt to use computeIfAbsentwithout ever checking whether the operation would really modify the map.

请注意,Map此代码不会修改 ,但仍然必须是可变的,因为不可变映射可能会UnsupportedOperation在尝试使用时抛出异常,computeIfAbsent而无需检查操作是否真的会修改映射。



But in the end, there is nothing wrong with Optional. But note that the code in your question is wrong. The lambda expression you pass to the method Optional.orElseThrowis meant to supplythe desired exception, not to throw it:

但最终,没有任何问题Optional。但请注意,您问题中的代码是错误的。您传递给该方法的 lambda 表达式Optional.orElseThrow旨在提供所需的异常,而不是抛出它:

public static MyEnum fromString(String value) {
    return Optional.ofNullable(enumMap.get(value)).orElseThrow(() ->
        new IllegalArgumentException("Unsupported value: " + value) // just return it
    );
}

回答by Misha

If you are willing to live with NullPointerException, you can do:

如果你愿意和 一起生活NullPointerException,你可以这样做:

public static MyEnum fromString(String value) {
    return requireNonNull(enumMap.get(value), () -> "Unsupported: " + value);
}

This assumes import static java.util.Objects.requireNonNull

这假设 import static java.util.Objects.requireNonNull

Edit:

编辑:

If you are really particular about what type of exception you throw, just implement your own static utility method:

如果您真的很在意抛出什么类型的异常,只需实现您自己的静态实用程序方法:

static<T, X extends Throwable> T nonNullOrThrow(T val, Supplier<? extends X> exSupplier) throws X {
    if (val != null) return val;
    else throw exSupplier.get();
}

Then you'll be able to do

然后你就可以做

return nonNullOrThrow(enumMap.get(value), () -> new IllegalArgumentException("unsupported: " + k));