Analisando um arquivo CSV para uma linha exclusiva usando a nova API Java 8 Streams
Estou tentando usar a nova API do Java 8 Streams (da qual sou um novato completo) para analisar uma linha específica (aquela com 'Neda' na coluna de nome) em um arquivo CSV. Usando o seguinteartigo por motivação, modifiquei e corrigi alguns erros para poder analisar o arquivo contendo 3 colunas - 'nome', 'idade' e 'altura'.
name,age,height
Marianne,12,61
Julie,13,73
Neda,14,66
Julia,15,62
Maryam,18,70
O código de análise é o seguinte:
@Override
public void init() throws Exception {
Map<String, String> params = getParameters().getNamed();
if (params.containsKey("csvfile")) {
Path path = Paths.get(params.get("csvfile"));
if (Files.exists(path)){
// use the new java 8 streams api to read the CSV column headings
Stream<String> lines = Files.lines(path);
List<String> columns = lines
.findFirst()
.map((line) -> Arrays.asList(line.split(",")))
.get();
columns.forEach((l)->System.out.println(l));
// find the relevant sections from the CSV file
// we are only interested in the row with Neda's name
int nameIndex = columns.indexOf("name");
int ageIndex columns.indexOf("age");
int heightIndex = columns.indexOf("height");
// we need to know the index positions of the
// have to re-read the csv file to extract the values
lines = Files.lines(path);
List<List<String>> values = lines
.skip(1)
.map((line) -> Arrays.asList(line.split(",")))
.collect(Collectors.toList());
values.forEach((l)->System.out.println(l));
}
}
}
Existe alguma maneira de evitar a leitura do arquivo após a extração da linha de cabeçalho? Embora este seja um arquivo de exemplo muito pequeno, aplicarei essa lógica a um arquivo CSV grande.
Existe uma técnica para usar a API de fluxos para criar um mapa entre os nomes das colunas extraídas (na primeira varredura do arquivo) para os valores nas linhas restantes?
Como posso retornar apenas uma linha na forma deList<String>
(ao invés deList<List<String>>
contendo todas as linhas). Eu preferiria apenas encontrar a linha como um mapeamento entre os nomes das colunas e seus valores correspondentes. (um pouco como um conjunto de resultados no JDBC). Eu vejo uma função Collectors.mapMerger que pode ser útil aqui, mas não tenho idéia de como usá-la.