我想创建方法,它将使用可选功能并返回值NodeId。我应该从Asset对象中提取该值。在某些情况下,我已经使用了诸如ifPresent,filter,flatMap之类的功能。但是现在我想清楚地了解是否可以通过下面的示例中的简单方法使用Optional,我只需要从另一个对象中提取值第一个例子据说不是很好,但是我尝试使用Optional:
public Optional<NodeId> findParentNodeIdByAsset(Asset asset) {
Optional<Asset> tmpAsset = Optional.ofNullable(asset);
if(tmpAsset.isEmpty()) {
throw new NullPointerException();
}
return Optional.ofNullable(tmpAsset.get().getParents().iterator().next());
}
在第二个示例中,我尝试编写相同的内容,但没有可选的内容:
public NodeId tmpFindParentNodeIdByAsset(Asset asset) {
if(Objects.isNull(asset)) {
throw new NullPointerException();
}
return asset.getParents().iterator().next();
}
在这些情况下,如果要抛出null
,则没有必要检查asset
tmpAsset
或是否为空NullPointerException
。
只需写:
public NodeId tmpFindParentNodeIdByAsset(Asset asset) {
return asset.getParents().iterator().next();
}
如果尝试取消引用空引用,则会抛出NullPointerException
。
现在,如果您不想抛出Optional
或NullPointerException
不是唯一可能是asset
的引用,则使用null
会很有用。
例如,假设asset.getParents()
也可以是null
,并且在asset
或asset.getParents()
为空的情况下,您想返回一些默认值,或者返回空的Optional
。
您可以链接多个map()
调用,以将每个潜在的null
引用转换为下一个潜在的null
引用,并以Optional
(如下面的示例所示),默认值或异常结束。
public Optional<NodeId> findParentNodeIdByAsset(Asset asset) {
return Optional.ofNullable(asset)
.map(asset -> asset.getParents())
.map(parents -> parents.iterator().next());
}
此外,在尝试获取parents
的第一个元素之前检查Iterator
是否为空可能更安全。
您在第一种方法中并未正确使用Optional
,在要返回NullPointerException
的方法中抛出Optional
并没有多大意义。请参阅Eran的答案以正确使用。
但是,如果您[NullPointerException
时抛出null
,则可以改用它:
public NodeId tmpFindParentNodeIdByAsset(Asset asset) {
Objects.requireNonNull(asset, "asset");
return asset.getParents().iterator().next();
}
public NodeId tmpFindParentNodeIdByAsset(Asset asset) {
return Optional.ofNullable(asset)
.map(asset -> asset.getParents().iterator().next())
.orElseThrow(UnsupportedOperationException::new)
}
否则,如果要返回可选的,只需删除orElseThrow()。对于每种可能返回null的getParents(),iterator()或next()方法,都应创建一个映射链,以免落入NPE中。例如:
public Optional<NodeId> tmpFindParentNodeIdByAsset(Asset asset) { return Optional.ofNullable(asset) .map(asset -> asset.getParents()) .map(parents -> parents.iterator().next()); }