47

I have a collection of Strings, and I would like to convert it to a collection of strings were all empty or null Strings are removed and all others are trimmed.

I can do it in two steps:

final List<String> tokens =
    Lists.newArrayList(" some ", null, "stuff\t", "", " \nhere");
final Collection<String> filtered =
    Collections2.filter(
        Collections2.transform(tokens, new Function<String, String>(){

            // This is a substitute for StringUtils.stripToEmpty()
            // why doesn't Guava have stuff like that?
            @Override
            public String apply(final String input){
                return input == null ? "" : input.trim();
            }
        }), new Predicate<String>(){

            @Override
            public boolean apply(final String input){
                return !Strings.isNullOrEmpty(input);
            }

        });
System.out.println(filtered);
// Output, as desired: [some, stuff, here]

But is there a Guava way of combining the two actions into one step?

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • as skaffman notes, that's about the most straightforward way to do it; as to your note about some pretty commonly used functions not being baked in - why not request the `Strings` api add some static `Function` s and `Predicate` s for sensible examples like this? I've found the maintainers at http://code.google.com/p/guava-libraries/issues/list reasonably responsive. – Carl Nov 25 '10 at 17:06
  • @Carl well I already have to issues in the pipeline there http://code.google.com/p/guava-libraries/issues/list?can=2&q=reporter:sean,mostlymagic.com and I don't want to get on their nerves. But I might just do that, because eventually I'd like Guava to replace commons/lang and commons/io for me and it still has a long way to go for that. – Sean Patrick Floyd Nov 25 '10 at 17:17
  • 2
    I think you could filter, and then transform. So don't need to test the null case in your transformation – sly7_7 Nov 26 '10 at 14:31
  • @sylvain: true, obviously. Thanks – Sean Patrick Floyd Nov 26 '10 at 14:39

1 Answers1

80

In the upcoming latest version(12.0) of Guava, there will be a class named FluentIterable. This class provides the missing fluent API for this kind of stuff.

Using FluentIterable, you should be able doing something like this:

final Collection<String> filtered = FluentIterable
    .from(tokens)
    .transform(new Function<String, String>() {
       @Override
       public String apply(final String input) {
         return input == null ? "" : input.trim();
       }
     })
    .filter(new Predicate<String>() {
       @Override
       public boolean apply(final String input) {
         return !Strings.isNullOrEmpty(input);
       }
     })
   .toImmutableList();
Pang
  • 9,564
  • 146
  • 81
  • 122
Olivier Heidemann
  • 1,337
  • 10
  • 14