我可以装饰Joiner类的番石榴

Pre*_*raj 13 java guava

我有一个List<String>,我们正在使用Joiner来获得该列表的逗号分隔表示,但现在我们需要做一点改进,我们需要大写列表中的值.现在代码是 -

String str = Joiner.on(',').skipNulls().join(myValueList);
Run Code Online (Sandbox Code Playgroud)

但是现在因为我需要将值中的字符串大写,我需要首先迭代它以大写然后传递给Joiner加入,但我不认为这是一个好方法,因为它将迭代List两次,一次到大写,然后Joiner将迭代加入.
是否有任何其他实用方法我可能会在一次迭代中执行此操作.

你会怎么用番石榴做的?

Joa*_*uer 21

您可以使用 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);
Run Code Online (Sandbox Code Playgroud)

  • @Grzegorz:一个优点是你不创建`myValueList`的副本.延迟返回的`Iterable`调用指定的方法,因此可能安全一些内存.我同意代码看起来不太好.不幸的是,Java不会很快关闭. (5认同)

Sea*_*oyd 15

关于Joachim Sauer的回答:

如果将函数移动到可以重复使用的地方,它可以减少冗长,在Guava中,典型的场景是使用枚举:

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);

}
Run Code Online (Sandbox Code Playgroud)

现在客户端代码如下所示:

String str =
    Joiner
        .on(',')
        .skipNulls()
        .join(
            Iterables.transform(myValueList,
                StringTransformations.UPPERCASE));
Run Code Online (Sandbox Code Playgroud)

我称之为更具可读性.

当然,如果你为Joiner引入了一个常量,它会更好(在内存使用和性能方面):

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

// ...

String str = COMMA_JOINER.join(
            Iterables.transform(myValueList,
                StringTransformations.UPPERCASE));
Run Code Online (Sandbox Code Playgroud)

  • 我认为最好的做法是*始终*将函数公开为静态工厂,以实现灵活性(泛型或非泛型).实现通常会使用枚举单例模式,但它是一个实现细节,可能会更改.另外,当使用枚举时,所有函数必须具有相同的泛型类型(在同一个枚举中不能同时具有Function <Integer,String>和Function <String,String>).Guava也是这样做的:http://code.google.com/p/guava-libraries/source/browse/trunk/src/com/google/common/base/Functions.java?r = 138#48(参见toStringFunction( )/ identity()). (8认同)
  • 我喜欢使用`enums`的想法!我一直在使用返回`Function`对象的静态方法,但这更清晰. (5认同)
  • 无论如何,当需要在某些通用边界内返回Function时,有时需要静态方法.Guava的许多静态工厂方法在内部使用枚举,但需要工厂方法才能进行泛型的翻译. (3认同)