Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I decorate Joiner class of Guava

Tags:

java

guava

I have a List<String> and we are using Joiner to get the comma separated presentation of that List but now we need to do little enhancement, We need to capitalize the values in the List. Now the code was -

String str = Joiner.on(',').skipNulls().join(myValueList);

But now as I need to capitalize the Strings present in values I need to iterate it first to capitalize and then pass to Joiner to join, but I den't think this is a good approach as it'll iterate the List twice, one to capitalize and then Joiner will iterate to Join.
Is there any other utility method that I'm missing which may do this in one iteration.

How will you do it with Guava?

like image 692
Premraj Avatar asked Feb 18 '11 11:02

Premraj


2 Answers

You can use Iterables.transform()

Iterable<String> upperStrings = Iterables.transform(myValueList, new Function<String,String>() {
  public String apply(String input) {
    // any transformation possible here.
    return (input == null) ? null : input.toUpperCase();
  }
});
Str str = Joiner.on(',').skipNulls().join(upperStrings);
like image 162
Joachim Sauer Avatar answered Nov 18 '22 13:11

Joachim Sauer


About Joachim Sauer's answer:

it can be made a lot less verbose if you move the Function to a place where it can be re-used, in Guava the typical scenario would be to use an enum:

public enum StringTransformations implements Function<String, String>{
    LOWERCASE{

        @Override
        protected String process(final String input){
            return input.toLowerCase();
        }
    },
    UPPERCASE{
        @Override
        protected String process(final String input){
            return input.toUpperCase();
        }
    }
    // possibly more transformations here
    ;

    @Override
    public String apply(final String input){
        return input == null ? null : process(input);
    }

    protected abstract String process(String input);

}

Now the client code looks like this:

String str =
    Joiner
        .on(',')
        .skipNulls()
        .join(
            Iterables.transform(myValueList,
                StringTransformations.UPPERCASE));

Which I'd call much more readable.

Of course it would be even better (in terms of both memory usage and performance) if you introduced a constant for your Joiner:

private static final Joiner COMMA_JOINER = Joiner.on(',').skipNulls();

// ...

String str = COMMA_JOINER.join(
            Iterables.transform(myValueList,
                StringTransformations.UPPERCASE));
like image 15
Sean Patrick Floyd Avatar answered Nov 18 '22 13:11

Sean Patrick Floyd