Java 8 Stream String Null или Empty Filter

У меня есть Гуава в потоке:

this.map.entrySet().stream()
.filter(entity -> !Strings.isNullOrEmpty(entity.getValue()))
.map(obj -> String.format("%s=%s", obj.getKey(), obj.getValue()))
.collect(Collectors.joining(","))

Как видите, внутри функции фильтра есть оператор !String.isNullOrEmpty(entity).

Я больше не хочу использовать Guava в проекте, поэтому просто хочу заменить его просто:

string == null || string.length() == 0;

Как я могу сделать это более элегантно?

Ответ 1

Вы можете написать свой собственный предикат:

final Predicate<Map.Entry<?, String>> valueNotNullOrEmpty
    = e -> e.getValue() != null && !e.getValue().isEmpty();

Затем просто используйте valueNotNullOrEmpty в качестве аргумента фильтра.

Ответ 2

Если вы предпочитаете использовать commons-lang3, StringUtils имеет

  • isEmpty()
  • isNotEmpty()
  • isBlank()
  • isNotBlank()

Эти методы могут использоваться в фильтрах как ссылки на методы:

this.stringList.stream().filter(StringUtils::isNotBlank);

или как lambdas:

this.stringList.stream().filter(s -> StringUtils.isNotBlank(s));

Ответ 3

Вы можете создать свой собственный класс Strings со своим собственным предикатом:

public class Strings {
  public static boolean isNotNullOrEmpty (String str) {
    return str != null && !str.isEmpty();
  }
}

Затем в вашем коде:

.filter(Strings::isNotNullOrEmpty)

Но, как упоминалось в @fge, вы не можете использовать это на Map.Entry<?,?>...

Ответ 4

Вы можете разбить фильтр на два этапа:

this.map.entrySet().stream()
    .filter(entity -> entity.getValue() != null)
    .filter(entity -> !entity.getValue().isEmpty())
    .map(obj -> String.format("%s=%s", obj.getKey(), obj.getValue()))
    .collect(Collectors.joining(","))

На стороне примечания, большинство реализаций Map.Entry.toString() делают именно то, что вы делаете в map(), поэтому теоретически вы можете просто сделать map(Map.Entry::toString). Но я бы не стал полагаться на это, если вы не создаете toString() или что-то, что не требует документированного или детерминированного поведения.

Кроме того, я знаю, что вы хотите отказаться от Guava, но вот решение, которое может заставить вас пересмотреть:

Joiner.on(',').withKeyValueSeparator("=")
      .join(Maps.filterValues(map, Predicates.not(Strings::isNullOrEmpty)));

Ответ 5

В Java 11 есть новый метод Predicate :: not.

Таким образом, вы можете отфильтровать пустую строку:

list.stream()
  .filter(Objects::nonNull)
  .filter(Predicate.not(String::isEmpty))

Ответ 6

Это работает для меня: list.stream().filter(el-> el != null && !el.toString().trim().isEmpty()).collect(Collectors.toList());