当条件涉及可选时,如何避免使用两个过滤器
How do I avoid two filters when condition involves an Optional
我有这样的代码:
myList.stream()
.filter(item -> item.getName().isPresent())
.filter(item -> item.getName().get().equalsIgnoreCase(otherName))
.findFirst();
(... 其中 item.getName()
的 return 类型为 Optional<String>
)
如何将两个过滤器压缩为一个?
您可以使用 Optional.filter()
:
myList.stream()
.filter(item ->
item.getName().filter(n -> n.equalsIgnoreCase(otherName)).isPresent())
.findFirst();
内部 filter
调用是 Optional.filter
,如果不满足过滤条件,returns 为空可选。
我会用“OOP”方式解决它。在 Item 'isNameEqual' 或类似的方法中创建一个方法,该方法将使用可选和忽略大小写隐藏逻辑。
那么你可以只有 1 个过滤器语句 Item::isNameEqual。
你不想在 lambda 中有太多的仪式。
使用逻辑与 (&&
) 合并过滤器:
myList.stream()
.filter(item -> item.getName().isPresent()
&& item.getName().get().equalsIgnoreCase(otherName))
.findFirst();
这是安全的,因为如果该值不存在,&&
将短路为 false。
或者使用条件运算符:
myList.stream()
.filter(item -> item.getName().isPresent()
? item.getName().get().equalsIgnoreCase(otherName)
: false)
.findFirst();
另一种方法是使用 null
作为值,如果 Optional<String>
没有值并且 equalsIgnoreCase(null)
将始终 return false
:
myList.stream()
.filter(item -> otherName.equalsIgnoreCase(item
.getName()
.orElseGet(null)))
.findFirst();
你可以用Optional::stream()
方法避免它:
If a value is present, returns a sequential Stream containing only that value, otherwise returns an empty Stream.
myList.stream()
.map(Item::getName)
.flatMap(Optional::stream)
.filter(otherName::equalsIgnoreCase)
.findFirst();
我有这样的代码:
myList.stream()
.filter(item -> item.getName().isPresent())
.filter(item -> item.getName().get().equalsIgnoreCase(otherName))
.findFirst();
(... 其中 item.getName()
的 return 类型为 Optional<String>
)
如何将两个过滤器压缩为一个?
您可以使用 Optional.filter()
:
myList.stream()
.filter(item ->
item.getName().filter(n -> n.equalsIgnoreCase(otherName)).isPresent())
.findFirst();
内部 filter
调用是 Optional.filter
,如果不满足过滤条件,returns 为空可选。
我会用“OOP”方式解决它。在 Item 'isNameEqual' 或类似的方法中创建一个方法,该方法将使用可选和忽略大小写隐藏逻辑。
那么你可以只有 1 个过滤器语句 Item::isNameEqual。
你不想在 lambda 中有太多的仪式。
使用逻辑与 (&&
) 合并过滤器:
myList.stream()
.filter(item -> item.getName().isPresent()
&& item.getName().get().equalsIgnoreCase(otherName))
.findFirst();
这是安全的,因为如果该值不存在,&&
将短路为 false。
或者使用条件运算符:
myList.stream()
.filter(item -> item.getName().isPresent()
? item.getName().get().equalsIgnoreCase(otherName)
: false)
.findFirst();
另一种方法是使用 null
作为值,如果 Optional<String>
没有值并且 equalsIgnoreCase(null)
将始终 return false
:
myList.stream()
.filter(item -> otherName.equalsIgnoreCase(item
.getName()
.orElseGet(null)))
.findFirst();
你可以用Optional::stream()
方法避免它:
If a value is present, returns a sequential Stream containing only that value, otherwise returns an empty Stream.
myList.stream()
.map(Item::getName)
.flatMap(Optional::stream)
.filter(otherName::equalsIgnoreCase)
.findFirst();