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

212*_*212 11 java reduce lambda scala java-stream

我试图mkString在Java8中编写一个函数,一个Scala是有用的,mkString并遇到了两个问题,我可以使用一些帮助:

  1. 我无法创建mkString泛型Collection引用的第一个参数,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);
}
Run Code Online (Sandbox Code Playgroud)

Vla*_*eev 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(","));
Run Code Online (Sandbox Code Playgroud)

它有几个重载,类似于Scala的mkString.但是,此收集器仅接受CharSequences,因此您需要将值显式转换为字符串作为单独的map步骤.

此外,还有一种String.join方法,它也适用于CharSequences 的集合.如果您具体使用其中一个(例如List<String>),则使用此方法可能更方便,而不是首先将集合转换为流:

List<String> strings = ...;

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

// vs

String result = strings.stream().collect(Collectors.joining(","))
Run Code Online (Sandbox Code Playgroud)


Dim*_*ima 5

如果我正确记住了我的java,你可以声明参数类型,Collection<?>以便能够传递任何对象的集合.

至于咬掉隔板,我想,只会.substring(1)做你想要的.

  • 在这种情况下,`T`和`?`绝对是一回事.所以,这是一个品味问题.我个人更喜欢`?`因为它清楚地表明实现不使用或不需要类型信息,并且该集合旨在被变异.它也是呼叫站点差异的常见指标. (3认同)