Я бы решил эту проблему в два этапа: сначала прочитал заголовки, затем прочитал остальные строки:
static String[] headers(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine().split(",");
}
}
Теперь вы можете использовать описанный выше метод следующим образом:
String path = "sample.csv";
// Read headers
String[] headers = headers(path);
List<Map<String, String>> result = null;
// Read data
try (Stream<String> stream = Files.lines(Paths.get(path))) {
result = stream
.skip(1) // skip headers
.map(line -> line.split(","))
.map(data -> {
Map<String, String> map = new HashMap<>();
for (int i = 0; i < data.length; i++) {
map.put(headers[i], data[i]);
}
return map;
})
.collect(Collectors.toList());
}
Вы можете изменить цикл for
внутри 2-й операции map
:
try (Stream<String> stream = Files.lines(Paths.get(path))) {
result = stream
.skip(1) // skip headers
.map(line -> line.split(","))
.map(data -> IntStream.range(0, data.length)
.boxed()
.collect(Collectors.toMap(i -> headers[i], i -> data[i])))
.collect(Collectors.toList());
}
РЕДАКТИРОВАТЬ: Если вместо сбора в список вы хотитечтобы выполнить действие для карт, считываемых из каждой строки, вы можете сделать это следующим образом:
try (Stream<String> stream = Files.lines(Paths.get(path))) {
stream
.skip(1) // skip headers
.map(line -> line.split(","))
.map(data -> IntStream.range(0, data.length)
.boxed()
.collect(Collectors.toMap(i -> headers[i], i -> data[i])))
.forEach(System.out::println);
}
(здесь действие состоит в печати каждой карты).
Эта версия может быть улучшенато есть он упаковывает поток int
с, а затем снова распаковывает каждый int
, чтобы использовать его в качестве индекса массивов headers
и data
.Кроме того, удобочитаемость может быть улучшена путем извлечения создания каждой карты в частный метод.
Примечания: Возможно, чтение файла дважды - не лучший подход с точки зрения производительности, но код прост и выразителен.Помимо этого, null
обработка, преобразование данных (т. Е. В числа или даты и т. Д.) И граничные случаи (т. Е. Без заголовков, без строк данных или различной длины для массивов данных и т. Д.) Остаются в качестве упражнения для читателя.;)