簡體   English   中英

Java 流可選 null 檢查兩項

[英]Java streams optional with null check on two items

我有以下代碼適用於兩個值,即。 一個String List和一個String ListString都可以是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);

想法是:如果myStringListnull ,則結果為空ArrayList 如果myStringnull ,則按原樣返回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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM