Java流可选,对两个项目进行空值检查

yhqotfr8  于 2023-01-11  发布在  Java
关注(0)|答案(4)|浏览(106)

我有下面的代码,它可以处理两个值,即StringListStringListString都可以是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不为空,则循环遍历列表并返回所有匹配myString的项。
问题是,使用上面的解决方案,即使myString为空,我仍然循环遍历整个列表(strings.stream)。
假设myStringList非常大,那么在myString为空的情况下,如何避免循环列表呢?
就是说
1)对列表做一个空值检查。2如果为空,返回一个新的空列表。
2)在myString上做一个空值检查。如果为空值,则不带循环返回列表。
3)如果myString不为空,则循环遍历列表并返回过滤后的列表。

kknvjkwl

kknvjkwl1#

你可以用三元的,

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);
}
68bkxrlz

68bkxrlz2#

这可能适合您(使用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);
nkhmeac6

nkhmeac63#

其他解决方案

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);
muk1a3rh

muk1a3rh4#

就我个人而言,我认为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-common

return N.isNullOrEmpty(myString) ? N.newArrayList(myStringList) 
                                 : N.filter(myStringList, e -> myString.equals(e));

相关问题