如何引用Java 8中reduce()操作的结果?

时间:2019-02-02 19:44:02

标签: java scala lambda java-stream reduce

我试图写一个mkString在Java8功能,斯卡拉的有用mkString跑进2个问题,我可以在使用一些帮助:

  1. 我无法作出的第一个参数mkString的通用集合的参考像Collection<Object> c,并具有调用器与任何类型的集合的调用。

  2. 无法直接引用返回的reduce()结果以访问结果的长度以删除多余的前导分隔符。

这是代码:

public static void main(String[] args) {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    System.out.println(mkString(numbers, ","));

}

public static String mkString(Collection<Integer> c, String sep) {
    return c.stream()
            .map(e -> String.valueOf(e))
            .reduce("", (a, b) -> a + sep + b)
            .substring(1, <<>>.length);
}

5 个答案:

答案 0 :(得分:11)

请注意,如果您这样做不是为了自我教育,而是为了在某些生产代码中实际使用它,则可能需要考虑内置的Collectors.joining收集器:

String result = numbers.stream()
    .map(Object::toString)
    // or
    //   .map(x -> x.toString())  // exactly the same
    // or
    //   .map(String::valueOf)    // handles nulls by turning them to the string "null"
    .collect(Collectors.joining(","));

它具有多个重载,类似于Scala的mkString。尽管如此,该收集器仅接受CharSequence,因此您需要将值显式转换为字符串,作为单独的map步骤。

此外,还有String.join方法,该方法也适用于CharSequence的集合。如果您明确地拥有其中一种(例如List<String>),则使用此方法可能比将集合首先转换为流更方便:

List<String> strings = ...;

String result = String.join(",", strings);

// vs

String result = strings.stream().collect(Collectors.joining(","))

答案 1 :(得分:5)

如果我没记错我的Java,可以将参数类型声明为Collection<?>,以便能够传递任何对象的集合。

至于咬过分离,我想,只是.substring(1)会做你想要什么。

答案 2 :(得分:4)

您可以这样做:

public static <T>  String mkString(Collection<T> c, String sep) { // generic impl
    return c.stream()
            .map(String::valueOf)
            .reduce("", (a, b) -> a + sep + b)
            .substring(1); // substring implementation to strip leading character
}

答案 3 :(得分:1)

Java中

任何类型的集合的意思是Collection<?>,在语义上与Collection<T>相同(在您的情况下),据说如果使用type参数(仅一次)可以安全地用通配符替换。但是,由于您希望能够连接任何集合,因此还应该要求调用者提供一个Function,该类型将从该类型转换为String表示形式,因此您的方法将变为:

public static <T> String mkString(Collection<T> c,
                                  Function<T, ? extends CharSequence> mapper,
                                  String sep) {
    return c.stream()
            .map(mapper)
            .collect(Collectors.joining(sep));

}

答案 4 :(得分:0)

可以利用String.join与通用类型:

public static <T> String mkString(Collection<T> c, String sep) {
    return String.join(sep, c.stream()
                             .map(e -> String.valueOf(e))
                             .collect(Collectors.toList()));
}

Here it is与两个字符串和其他目的的行动。