短路Java可选。flatMap()
使用Java的短路Java可选。flatMap(),java,optional,Java,Optional,使用Java的Optional.flatMap()有一个有趣的难题。我有一个类,它以“foo:bar”或“bar”的形式封装了。我还有一个类,用于向名称空间注册前缀,以及跟踪默认名称空间。它有一个方法findNamespaceByPrefix()返回一个可选的(因为前缀可能没有注册)和一个方法getDefaultNamespace(),也返回一个可选的(因为可能没有默认的命名空间) 给定一些居里数,我想找到名称空间。这很吸引人: Optional namespace=curie.getPrefi
Optional.flatMap()
有一个有趣的难题。我有一个类,它以“foo:bar”
或“bar”
的形式封装了。我还有一个类,用于向名称空间注册前缀,以及跟踪默认名称空间。它有一个方法findNamespaceByPrefix()
返回一个可选的(因为前缀可能没有注册)和一个方法getDefaultNamespace()
,也返回一个可选的(因为可能没有默认的命名空间)
给定一些居里数,我想找到名称空间。这很吸引人:
Optional namespace=curie.getPrefix()
.flatMap(this::findNamespaceByPrefix)
.或(此::getDefaultNamespace);
但这是错误的。问题是它返回默认名称空间,即使有前缀但没有与该前缀关联的名称空间。如果CURIE中没有任何前缀,我们只想返回默认名称空间(如果有)
以下是一个解决方案:
Optional prefix=curie.getPrefix();
可选名称空间=前缀.isPresent()
? prefix.flatMap(this::findNamespaceByPrefix)
:getDefaultNamespace();
我对此很满意,但我觉得使用三元运算符有点不起作用,并且使用可选。isPresent()
通常表示有更好的方法来做事情
是否有可选的专家有更好、更实用的解决方案来“短路”平面映射?(我有一种预感,我可以通过使用Optional:of
和Optional:get
来完成几层包装和展开Optional
,但是否有更优雅的东西?你应该保留第二层可选:
Optional<URI> namespace = curie.getPrefix()
.map(Application::findNamespaceByPrefix)
.orElseGet(Application::getDefaultNamespace);
Optional namespace=curie.getPrefix()
.map(应用程序::findNamespaceByPrefix)
.OrelGet(应用程序::getDefaultNamespace);
map
操作将前缀(如果存在)映射到一个包装的Optional
,该前缀为空(如果没有前缀),或包含一个空(如果找不到前缀的命名空间)或包含实际命名空间的Optional
只有当包装可选的为空且您的前缀不存在时,才会调用外部orElseGet
。检查是否有空前缀
Optional<URI> namespace = prefix
.filter(Objects::nonNull)
.flatMap(this::findNamespaceByPrefix)
.or(this::getDefaultNamespace);
可选名称空间=前缀
.filter(对象::非空)
.flatMap(this::findNamespaceByPrefix)
.或(此::getDefaultNamespace);
您可以按如下方式进行测试:
public static void main(String[] args) {
test(Optional.ofNullable(null));
test(Optional.ofNullable("yourprefix"));
}
private static void test(Optional<String> prefix) {
Optional<URI> namespace2 = prefix
.filter(Objects::nonNull)
.flatMap(p -> Optional.of(URI.create(p)))
.or(() -> Optional.of(URI.create("default")));
System.out.println(namespace2);
}
publicstaticvoidmain(字符串[]args){
测试(可选的空值);
测试(可选。不可用(“您的前缀”);
}
专用静态无效测试(可选前缀){
可选名称空间2=前缀
.filter(对象::非空)
.flatMap(p->Optional.of(URI.create(p)))
.或(()->可选的(URI.create(“default”));
System.out.println(名称空间2);
}
是!就是这样!我有一种预感,我需要保留可选的
,但我对如何摆脱它感到困惑。我想这就是解决办法!问题在于flatMap()
将名称空间丢失的两个不同原因合并在一起。此解决方案将两者分开,不会混淆。在您的示例中,变量前缀是什么类型的?它是字符串类型的吗?它是可选类型的吗?它是流
类型吗?还是别的?@GarretWilson,它是Optional prefix=Optional.ofNullable(“您的前缀或null,如果不存在”)代码>当可选
不能包含空
值时,如何通过对象::非空
过滤可选
值?对可选的执行这样的操作难道不是毫无意义的吗?@GarretWilson编译代码必须是可选的,与问题中相同。但是仍然没有解决这个问题,忽略那里的第一个代码块。不,可选。空值(null)
将不包含null
值。它将不包含任何值;它将是空的。如果您不相信我,请尝试调用Optional.ofNullable(null.get()
)。