1

Good solution for not null string is:

Stream.of("REG", "UNREG").anyMatch(str::equals)

Taken from here :Compare one String with multiple values in one expression.

But how modify (or alter) it for nullable string (if the String is null return false)?

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
slider
  • 421
  • 1
  • 4
  • 19

3 Answers3

4

You might want to start with Optional instead and perform the Stream inside the Optional::map method. If no result is present (str was null), then return false as requested:

Optional.ofNullable(str)
        .map(string -> Stream.of("REG", "UNREG")         // Your Stream as at your snippet
                             .anyMatch(string::equals))  // Returns if the str matches any
        .orElse(false);                                  // Returns false if str is null

Don't underestimate a simple:

str != null && Stream.of("REG", "UNREG").anyMatch(str::equals);

In case the first expression is false (when str is null), the second part of the expression will not be evaluated thus never fails on NPE inside of Stream::anyMatch.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
2

The simplest solution would be to use Arrays.asList + List.contains:

Arrays.asList("REG", "UNREG").contains(str)

Note that:

  1. In both this and your Stream-based solution there's a single array allocation.
  2. However, such approach makes sense only for regular equals (so comparison using e.g. equalsIgnoreCase is not possible here).
Tomasz Linkowski
  • 4,386
  • 23
  • 38
  • This differs from the requirement “if the String is `null` return `false`”, as `contains(null)` may return `true` if there is a `null` element. If the requirement allowed returning `true `if `str` is `null` and the `Stream` has a `null` element, `Stream.of(…).anyMatch(Predicate.isEqual​(str))` would be an alternative. – Holger Aug 11 '18 at 10:53
  • Well, you took the requirement very literally. I believe the OP did not mean that because such behavior (`null` here and `null` there returning `false`) would be very unintuitive. – Tomasz Linkowski Aug 11 '18 at 14:20
  • Well yes, I took it very literally (like Nikolas’ answer), but was open to the other possibility. As I said, if matching `null` elements is intended, you can also use `.anyMatch(Predicate.isEqual​(str))` if you already have an existing stream and no way to rewrite the code to produce a collection ala `Arrays.asList`. – Holger Aug 13 '18 at 12:41
  • OK, so we made different assumptions regarding where the strings come from. I assumed that the OP looks for an idiom to test for equality with a few `String`s known at compile-time, like `if ("REG".equals(str) || "UNREG".equals(str))` -> `if (Arrays.asList("REG", "UNREG").contains(str))`. Actually, now that I have looked at the [question he referenced](https://stackoverflow.com/questions/10205437/compare-one-string-with-multiple-values-in-one-expression), it seems that's what he wants. But if he had the `String`s from some other source, your `Stream`-based solution would indeed be much better. – Tomasz Linkowski Aug 13 '18 at 13:11
0

Why not just invert the equals clause:

boolean contained = Stream.of("REG", "UNREG").anyMatch(s -> s.equals(str));

So if str is null it will not match any of the Strings in the stream and thus returns false.

Lino
  • 19,604
  • 6
  • 47
  • 65