检查 Java 可选映射管道中的枚举 valueOf

问题描述 投票:0回答:2

我有以下方法,在这里我首先获取

exportProductType
的名称,然后获取该名称的值。如果
name
valueOf(name)
为 null,则抛出异常。

public static ProductType getExportProductType(ExportProductType exportProductType) {
    return Optional.ofNullable(exportProductType)
            .map(ExportProductType::name)
            .map(ProductType::valueOf)
            .orElseThrow(() -> new ProductTypeNotFoundException());
}

一切正常,工作没有任何问题。但是,当我传递

exportProductType
枚举中不可用的
ProductType
枚举值时,我无法捕获它,并且会抛出另一个异常“没有枚举常量...”。所以,我想我需要在
ProductType::valueOf
之前检查
.map(ProductType::valueOf)
是否为空。我应该如何检查?使用布尔值或过滤器?或者另一种适合 Java 中
stream()
的方法?

我想在

.map(ExportProductType::name)
之后会有类似的事情:

.filter(result -> ProductType::valueOf(result) != null)


更新:我找到了正确的方法,如下所示:

EnumUtils.isValidEnum(ProductType.class, exportProductType.name());

我只需要在

stream()
中使用它即可。那么,是否可以在
stream()
中进行相同的检查?就在
.map(ExportProductType::name)
线下方可以吗?

.filter(x -> EnumUtils.isValidEnum(ProductType.class, x))

java spring enums java-stream option-type
2个回答
1
投票

正如评论中提到的,必须处理

IllegalArgumentException
valueOf
,因此,例如,您可以定义自己的值查找方法,该方法将返回一个空的Optional,而不是抛出异常:

enum ProductType {
    ...
    
    static Optional<ProductType> nullableValueOf(String name) {
        try {
            return Optional.of(ProductType.valueOf(name));
        } catch (IllegalArgumentException ex) {
            return Optional.empty();
        }
   }
}

public static ProductType getExportProductType(ExportProductType exportProductType) throws ProductTypeNotFoundException {
    return Optional.ofNullable(exportProductType)
                   .map(ExportProductType::name)
                   .flatMap(ProductType::nullableValueOf)
                   .orElseThrow(() -> new ProductTypeNotFoundException());
}

编辑:

虽然您已经在使用

Optional
,但将它用作返回类型会更干净:

public static Optional<ProductType> getExportProductType(ExportProductType exportProductType) throws ProductTypeNotFoundException {
    return Optional.ofNullable(exportProductType)
                   .map(ExportProductType::name)
                   .flatMap(ProductType::nullableValueOf);
}

0
投票

Vavr这样的库实现了如下功能帮助器:

static <A, T> Function<A, Optional<T>> Try(Function<A, T> f) {
    return a -> {
        try {
            return Optional.of(f.apply(a));
        } catch (Exception ex) {
            return Optional.empty();
        }
    };
}

将异常包装成纯函数类型。有了这个,你可以映射、过滤等等......无效状态:

enum EnumX { Foo, Bar }

Stream
        .of("Foo", "Bar", "Par")
        .map(Try(EnumX::valueOf))
        .forEach(System.out::println);

Stream
        .of("Foo", "Bar", "Par")
        .map(Try(EnumX::valueOf))
        .filter(Optional::isPresent)
        .map(Optional::get)
        .forEach(System.out::println);

有输出

Optional[Foo]
Optional[Bar]
Optional.empty
Foo
Bar

注意:此处有完整运行的示例代码

import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;

public class EnumStreamCheck {

    static <A, T> Function<A, Optional<T>> Try(Function<A, T> f) {
        return a -> {
            try {
                return Optional.of(f.apply(a));
            } catch (Exception ex) {
                return Optional.empty();
            }
        };
    }

    public static void main(String... args) {

        Stream
                .of("Foo", "Bar", "Par")
                .map(Try(EnumX::valueOf))
                .forEach(System.out::println);

        Stream
                .of("Foo", "Bar", "Par")
                .map(Try(EnumX::valueOf))
                .filter(Optional::isPresent)
                .map(Optional::get)
                .forEach(System.out::println);
    }

    enum EnumX {
        Foo, Bar
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.