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

  • 我无法使mkString的第一个参数成为通用的Collection引用(例如Collection<Object> c),并且调用者使用任何类型的collection进行调用。
  • 无法直接引用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);
    }
    

    最佳答案

    请注意,如果您这样做不是为了自我教育,而是为了在某些生产代码中实际使用它,则可能需要考虑内置的 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(","))
    

    07-25 21:21