58

In Java 8 I have some number of String values and I want to end up with a comma delimited list of valid values. If a String is null or empty I want to ignore it. I know this seems common and is a lot like this old question; however, that discussion does not address nulls AND spaces (I also don't like the accepted answer).

I've looked at Java 8 StringJoiner, Commons StringUtils (join) and trusty Guava (Joiner) but none seems like a full solution. The vision:

 where: val1 = "a", val2 = null, val3 = "", val4 = "b"

  String niceString = StringJoiner.use(",").ignoreBlanks().ignoreNulls()
    .add(val1).add(val2).add(val3).add(val4).toString();

...would result in niceString = a,b

Isn't there a nice way to do this (that doesn't involve for loops, loading strings into a list, and/or regex replaces to remove bad entries)?

Lii
  • 11,553
  • 8
  • 64
  • 88
eze
  • 2,332
  • 3
  • 19
  • 30
  • 2
    http://stackoverflow.com/questions/31380784/java-8-stream-string-null-or-empty-filter – Savior Apr 18 '16 at 23:24
  • 6
    The straightforward java 8 way is `Stream.of(val1, val2, val3, val4).filter(s -> s!=null && !s.isEmpty()).collect(joining(","))` with a static import of `Collectors.joining`. If that's not to your liking, you would have to make your own class or find one in some library. But why bother? – Misha Apr 18 '16 at 23:30
  • 1
    dup by title perhaps but not intension. – eze Apr 18 '16 at 23:31
  • 5
    Does [this](http://stackoverflow.com/a/35570259/5191913) answer in Java 8 not do exactly what you are asking for? – Savior Apr 18 '16 at 23:31
  • 5
    Users need to get the idea that a duplicate is bad out of their heads. If a solution exists, we should point to it instead of splitting up the knowledge everywhere. – Savior Apr 18 '16 at 23:54

1 Answers1

170
String joined = 
    Stream.of(val1, val2, val3, val4)
          .filter(s -> s != null && !s.isEmpty())
          .collect(Collectors.joining(","));
Ahmet
  • 908
  • 1
  • 17
  • 26
Brian Goetz
  • 90,105
  • 23
  • 150
  • 161
  • 1
    There are quite a few related and duplicate questions. Please vote to close as such and provide your answers there if they apply. – Savior Apr 18 '16 at 23:32
  • 14
    @Pillar questions answered by Brian Goetz (one of main Java architects) automatically become questions which others should use as duplicate target (he is our Jon Skeet of Java 8). – Pshemo Apr 18 '16 at 23:40
  • 2
    @Brian what happens if all of var1, var2... are null? – Optimus Prime Jun 05 '18 at 10:15
  • 4
    @OptimusPrime The delimiter passed to `joining()` is a separator. If all the elements are null, they all get filtered, so the stream presented to `collect()` is empty. In that case, you'll get an empty string out. There are alternate versions of `joining()` that let you specify prefix and suffix too, in which case you'd get `prefix + suffix`. – Brian Goetz Jun 05 '18 at 13:57
  • Can I somehow get null instead of the empty string? – Optimus Prime Jun 05 '18 at 17:10
  • 3
    Yes, just use `collectingAndThen()` with a finishing function that maps `""` to `null`. – Brian Goetz Jun 05 '18 at 18:08
  • `Call requires API level 24 (current min is 16): java.util.stream.Stream` in Android – Pratik Butani Dec 18 '18 at 06:57
  • Might be even more readable by using Stringutils to check if the String is null or empty `StringUtils.isNotEmpty(s)` within the filter – Glenn Van Schil Jun 04 '21 at 12:21