我有以下方法,在这里我首先获取
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))
正如评论中提到的,必须处理
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);
}
像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
}
}