[英]Java streams optional with null check on two items
我有以下代碼適用於兩個值,即。 一個String
List
和一個String
。 List
和String
都可以是null
。
List<String> myStringList = getMyStringList(); // may return null
String myString = "abc"; // may be null
List<String> finalStringList = Optional.ofNullable(myStringList)
.map(strings -> strings.stream()
.filter(obj -> StringUtils.isEmpty(myString)
|| myString.equals(obj))
.collect(Collectors.toList()))
.orElseGet(ArrayList::new);
想法是:如果myStringList
是null
,則結果為空ArrayList
。 如果myString
是null
,則按原樣返回myStringList
。 如果myString
不是 null,則遍歷列表並返回與myString
匹配的所有項目。
問題是,使用上述解決方案,即使myString
為 null,我仍然會遍歷整個列表( strings.stream
)。
假設myStringList
非常大,當myString
為 null 時,如何避免循環列表?
那是,
1)對列表進行 null 檢查。 如果 null,返回一個新的空列表。
2)對myString
進行 null 檢查。 如果 null,不循環返回列表。
3)如果myString
不是null,循環遍歷列表,返回過濾后的列表。
你可以使用三元像,
List<String> finalStringList = myString == null ?
Collections.emptyList()
: Optional.ofNullable(myStringList)
.map(strings -> strings.stream()
.filter(obj -> StringUtils.isEmpty(myString)
|| myString.equals(obj))
.collect(Collectors.toList()))
.orElseGet(ArrayList::new);
或者一個基本的if
並且默認為一個空列表。 喜歡,
List<String> finalStringList = Collections.emptyList();
if (myString != null) {
finalStringList = Optional.ofNullable(myStringList)
.map(strings -> strings.stream()
.filter(obj -> StringUtils.isEmpty(myString)
|| myString.equals(obj))
.collect(Collectors.toList()))
.orElseGet(ArrayList::new);
}
這可能對您有用(使用 Java 9+):
List<String> result2 = Optional.ofNullable(myString)
.filter(Objects::nonNull)
.map(mystr -> Optional.ofNullable(myStringList)
.filter(Objects::nonNull)
.or(() -> Optional.of(new ArrayList<>()))
.stream()
.flatMap(List::stream)
.filter(mystr::equals)
.collect(Collectors.toList())) //ArrayList not guaranteed
.orElse(myStringList);
如果您使用的是 Java 8,則以下內容應該有效,但看起來有點難以閱讀:
List<String> result = Optional.ofNullable(myString)
.filter(Objects::nonNull)
.map(mystr -> Optional.ofNullable(myStringList)
.filter(Objects::nonNull)
.map(list -> list.stream()
.filter(mystr::equals)
.collect(Collectors.toList()))
.orElseGet(ArrayList::new))
.orElse(myStringList);
其他解決方案
List<String> myStringList = Arrays.asList("abc", "aef"); // may return null
String myString = "abc"; // may be null
Map<Predicate, Supplier<List<String>>> predicateMap = Map.of(
(v) -> myStringList == null, () -> new ArrayList<>(), // do a null check on the list. If null, return a new empty list.
(v) -> myString == null, () -> myStringList, // do a null check on myString. If null, return the list as is WITHOUT LOOPING.
(v) -> true, () -> myStringList.stream() // if myString is not null, loop through the list and return the filtered list.
.filter(myString::equals)
.collect(Collectors.toList())
);
List<String> outputList = predicateMap.entrySet().stream()
.filter(p -> p.getKey().test(null))
.findFirst().get().getValue().get();
System.out.println(outputList);
就個人而言,我認為if-else
的代碼將更具可讀性/可維護性/高效性:
if (myStringList == null || myStringList.size() == 0) {
return Collections.emptyList();
} else if (StringUtils.isEmpty(myString)) {
return new ArrayList<>(myStringList); // or return myStringList;
} else {
return myStringList.stream().filter(e -> myString.equals(e))
.collect(Collectors.toList());
}
好吧,如果你真的想避免寫幾行代碼,試試我的庫: abacus-util
return N.isNullOrEmpty(myString) ? N.newArrayList(myStringList)
: N.filter(myStringList, e -> myString.equals(e));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.