有没有办法简化这个流表达式?

时间:2014-09-26 07:35:06

标签: java arrays java-8 java-stream

protected static String paramsAsString(Object[] args) {
    return Arrays.stream(args).map((o) -> o != null && o.getClass().isArray() ? ArrayUtils.toString(o) : o)
            .collect(Collectors.toList()).toString();
}

单元测试

public void paramsAsString() throws Exception {
    String[] strings = {"1" , "2"};
    int[] ints = {3,4};
    int[] intsEmpty = {3,4};
    Object[] args = {"aaa" ,"zzz" , ints , strings, intsEmpty, null};
    String paramsAsString = paramsAsString(args);
    assertEquals("[aaa, zzz, {3,4}, {1,2}, {3,4}, null]", paramsAsString);
}

我只是在学习流API。 我想知道有没有办法简化这个流表达式并删除复杂的if?

2 个答案:

答案 0 :(得分:5)

如果您只是引用ArrayUtils::toString,则可以避免使用条件:

protected static String paramsAsString(Object[] args) {
    return Arrays.stream(args)
                 .map(ArrayUtils::toString)
                 .collect(Collectors.toList()).toString();
}

但是你的测试失败了:

[aaa, zzz, {3,4}, {1,2}, {3,4}, {}]

而不是

[aaa, zzz, {3,4}, {1,2}, {3,4}, null]

你可以" hack"这与正则表达式:

 return Arrays.stream(args)
              .map(ArrayUtils::toString)
              .collect(Collectors.toList())
              .toString().replaceAll("\\{\\}" , "null");
 }

但就个人而言,我会保留条件并将lambda转换为另一种实用方法:

public class MyArrayUtils {
     protected static String paramsAsString(Object[] args) {
         return Arrays.stream(args)
                      .map(MyArrayUtils::objectToString)
                      .collect(Collectors.toList()).toString();
     }

     private static String objectToString(Object object) {
         return object == null ? null : ArrayUtils.toString(object);
     }
}

答案 1 :(得分:4)

我不清楚您期望的输出是否真的是您想要的,或者它是否只是您当前代码的工件(即将第三方库方法ArrayUtils.toString(o)的输出与{{1 }})。

当您只使用Arrays.deepToString时,您已经获得了

List.toString

如果你真的想要使用"[aaa, zzz, [3, 4], [1, 2], [3, 4], null]" API作为练习或想要真正控制格式,你可以这样做:

使用Stream

java.lang.reflect.Array

这不会隐藏任何实用程序方法的用法,但能够自行格式化任何数组。并且它不会创建使用其public class MyArrayUtil { static String paramsAsString(Object o) { if(o==null) return "null"; if(!o.getClass().isArray()) return o.toString(); return IntStream.range(0, Array.getLength(o)) .mapToObj(i->Array.get(o, i)).map(MyArrayUtil::paramsAsString) .collect(Collectors.joining(", ", "{", "}")); } } 方法的中间List。相反,它使用适当的toString(),它允许您控制输出。在上面的示例中,我使用了Collector{,因此结果将是:

}

如果您想要更高的性能,可能会牺牲可读性并使用以下派生代码:

{aaa, zzz, {3, 4}, {1, 2}, {3, 4}, null}