流集合错误和理解

时间:2014-09-29 18:39:49

标签: java lambda collections java-8

我尝试使用java 8' Stream API读取CSV并从中创建矩阵。

这主要是为了学习Stream(当然,如果没有Stream s,还有其他方法可以做到这一点。)

以下是代码:

public class MatrixCreator {

    public static Function<String, List<Double>> mapLineToListOfDoubles = (line) -> {
        String [] elements = line.split(",\\s*");
        return Arrays.stream(elements).map((String stringElement) -> Double.parseDouble(stringElement)).collect(Collectors.toList());
    };

    //Error from this -- listed below
    public static Collector<List<Double>, List<Double>, List<Double>> listCollector = Collector.of(ArrayList<Double>::new, List<Double>::addAll, (ArrayList<Double> left, List<Double> right) -> {
        left.addAll(right);
        return left;
    });


    /**
     * Creates a matrix from the specified file.
     * @param filePath Path to CSV, matrix, file
     */
    public static Matrix createMatrix(String filePath) throws IOException {
        FileInputStream fileInputStream = new FileInputStream(filePath);
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
        List<Double> x = bufferedReader.lines().map(mapLineToListOfDoubles).collect(listCollector);
        return null;  // for the moment.
    }
}

给出以下错误:

Error:(26, 96) java: no suitable method found for of(ArrayList<[...]::new,List<Doubl[...]ddAll,(ArrayList[...]ft; })
    method java.util.stream.Collector.<T,R>of(java.util.function.Supplier<R>,java.util.function.BiConsumer<R,T>,java.util.function.BinaryOperator<R>,java.util.stream.Collector.Characteristics...) is not applicable
      (inferred type does not conform to equality constraint(s)
        inferred: java.util.List<java.lang.Double>
        equality constraints(s): java.util.List<java.lang.Double>,java.util.ArrayList<java.lang.Double>)
    method java.util.stream.Collector.<T,A,R>of(java.util.function.Supplier<A>,java.util.function.BiConsumer<A,T>,java.util.function.BinaryOperator<A>,java.util.function.Function<A,R>,java.util.stream.Collector.Characteristics...) is not applicable
      (cannot infer type-variable(s) T,A,R
        (actual and formal argument lists differ in length))

显然,Java无法确定要使用的方法,但我无法确定从何处开始。

我很感激有关此错误原因的任何帮助。

1 个答案:

答案 0 :(得分:1)

唯一可以匹配您提供的参数数量的Collector.of方法是:

static <T,R> Collector<T,R,R>   of(Supplier<R> supplier, BiConsumer<R,T> accumulator, BinaryOperator<R> combiner, Collector.Characteristics... characteristics)

您将返回类型声明为Collector<List<Double>, List<Double>, List<Double>>,因此TR都是List<Double>

但是,在参数列表中,组合器(第三个参数)接收一个lambda表达式,其中包含两个参数ArrayList<Double> leftList<Double> right,返回ArrayList<Double>。但是方法签名需要BinaryOperator<R>,这意味着两个参数+ lambda表达式的返回值必须是相同的类型。

我建议您将代码更改为:

public static Collector<List<Double>, List<Double>, List<Double>> listCollector = Collector.of(ArrayList<Double>::new, List<Double>::addAll, (List<Double> left, List<Double> right) -> {
    left.addAll(right);
    return left;
});

我不确定这是否是唯一的问题(我无法测试),但它很有可能,因为这是你从编译器得到的错误信息暗示:

  (inferred type does not conform to equality constraint(s)
    inferred: java.util.List<java.lang.Double>
    equality constraints(s): java.util.List<java.lang.Double>,java.util.ArrayList<java.lang.Double>)

错误消息的其余部分无关紧要,因为另一个Collector.of方法需要一个额外的参数,因此与您的代码无关。