2014-09-29 2 views
2

Я пытаюсь прочитать в CSV, используя API java 8 Stream и создать из него матрицу.Собрания потоков Ошибка и понимание

Это, в основном, для изучения Stream s (есть, конечно, другие способы сделать это без 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 не может определить, какой метод использовать, но я не могу определить, куда идти отсюда.

Буду признателен за причину этой ошибки.

+0

Вы делаете свою жизнь ненужной. Вы можете просто опустить типы из параметров лямбда, сохраняя много написания шаблонов и одновременно удаляя ошибку: '(слева, справа) -> {left.addAll (справа); вернуться влево; } '. То же самое относится к ссылкам метода: вам не нужно писать 'ArrayList :: new' или' List :: addAll'. Просто 'ArrayList :: new' или' List :: addAll' достаточно. Используйте силу вывода типа Java 8. И вы можете заменить '(String stringElement) -> Double.parseDouble (stringElement)' с 'Double :: parseDouble' – Holger

ответ

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>>, так как T и R являются List<Double>.

Однако в списке аргументов сумматор (третий аргумент) получает лямбда-выражение с двумя параметрами ArrayList<Double> left и List<Double> right, которое возвращает ArrayList<Double>. Но подпись метода ожидает BinaryOperator<R>, что означает, что оба параметра + возвращаемое значение лямбда-выражения должно быть одного типа.

Я предлагаю вам изменить ваш код:

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 метод ожидает дополнительный аргумент, и, следовательно, не относятся к коду.

+0

абсолютно. имеет смысл! Не заметил этого немного. Спасибо! – user2243357

Смежные вопросы