36

I've got Google Guava inside Stream:

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

As you see there is a statement !String.isNullOrEmpty(entity) inside the filter function.

I don't want to use Guava anymore in the project, so I just want to replace it simply by:

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

How can I do it more elegant?

9
  • use StringUtils (apache commons lang) or Optional.ofNullable(string).orElse("").length() ==0 Commented Jul 13, 2015 at 10:27
  • i want to use Pure Java - is possible to do it here? Commented Jul 13, 2015 at 10:32
  • 1
    Optional.ofNullable(string).orElse("").length() ==0 is pure java Commented Jul 13, 2015 at 10:32
  • @griFlo String has .isEmpty() so why bother doing the length() part at all? Commented Jul 13, 2015 at 10:35
  • 4
    Also, I don't see how the code can work; you cannot use Strings.isNullOrEmpty() on a Map.Entry<?, ?> Commented Jul 13, 2015 at 10:37

6 Answers 6

40

In java 11 there is a new method Predicate::not.

So you can filter out empty string :

list.stream()
  .filter(Objects::nonNull)
  .filter(Predicate.not(String::isEmpty))
Sign up to request clarification or add additional context in comments.

Comments

29

You can write your own predicate:

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

Then just use valueNotNullOrEmpty as your filter argument.

12 Comments

What about you showed the real code in your question, then? As I said, the current code extract just won't compile
Image won't display for me; and you can OMG all you want, this is a fact: the code you posted in the question will not compile.
@ServerSideCat: no, we can’t. We are programmers. Our work is based on facts, like that a Map.Entry is not a String. We can’t accept that code that claims otherwise shall work because you say “I see it working”. As it is not a matter of looking at it but understanding what’s going on. If you understood the point, you did everything to find out, where’s the mismatch. When obviously wrong code appears to work, it should make you nervous, especially when it is production code.
You are calling filter(…) on a entrySet().stream(), thus it expects a Predicate<Map.Entry<…>>. Point. Obviously, copying the code of your question can’t compile anyway since not even the definition of map is there. If you compared the code you have posted on that image hoster with the code you have posted in your question, you noticed the small getValue() call that is missing here, which makes a huge difference. You just failed to do a proper copy and paste.
@ServerSideCat, your screenshot has isNullOrEmpty(entity.getValue()) while in your question it's just isNullOrEmpty(entity).
|
24

If you prefer to use commons-lang3, StringUtils has

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

These methods can be used in filters as method references:

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

or as lambdas:

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

1 Comment

I think the isBlank() isNotBlank() methods are very useful, but just so others are aware, they are different than isNullOrEmpty() in that they also check for other whitespace characters such as tabs, carriage returns, etc. This is defined by the isWhiteSpace() function in Java: docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/…
9

You can create your own Strings class with your own predicate:

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

Then in your code:

.filter(Strings::isNotNullOrEmpty)

But as @fge mentionned, you can't use that on a Map.Entry<?,?>...

Comments

4

It works for me: list.stream().filter(el-> el != null && !el.toString().trim().isEmpty()).collect(Collectors.toList());

Comments

3

You can break down the filter into two steps:

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(","))

On a side note, most Map.Entry.toString() implementations do exactly what you're doing in map(), so you could theoretically just do map(Map.Entry::toString). But I wouldn't rely on that unless you're producing a toString() or something that doesn't require documented or deterministic behavior.

Also, I know you want to abandon Guava, but here's a solution that might make you reconsider:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.