概述
你的CSV看起来很奇怪,我不希望人们追加列,而是追加行,特别是当你有一个ID列来分隔行时.
也就是说,我将数据解析为Car对象,然后对其进行处理.这涉及三个步骤.
在文件的第一行,找到指示有趣列的标题字段,此处为carId和mph. Apache的CSV库在重复的标题名称上窒息(我不能真的责怪它),所以你需要找到一个更宽松的库或自己解析标题.
使用标题中的信息,您可以创建Car对象,告诉他们列.每辆车都负责自己的列号以及所有速度(您真正想要的信息).
然后你阅读文件的其余部分,并为他们的汽车分配速度.由于汽车拥有他们的数据(他们的列号和速度),你只需将每个记录字段传递给所有汽车,并要求他们采取行动,如果它们是他们的(Tell Don’t Ask principle).
您的Car类可能如下所示:
import java.util.List;
import java.util.ArrayList;
public class Car {
private int id;
private final int idColumn;
private final int speedColumn;
private List speeds;
public Car(int idColumn, int speedColumn) {
id = 0;
this.idColumn = idColumn;
this.speedColumn = speedColumn;
speeds = new ArrayList<>();
}
public void add(int column, String value) {
if (this.idColumn == column) {
int i = Integer.parseInt(value);
if (id != 0 && id != i) {
throw new IllegalStateException("changed ID from " + id + " to " + i);
}
id = i;
}
if (this.speedColumn == column) {
speeds.add(Integer.parseInt(value));
}
}
public List getSpeeds() {
return speeds;
}
}
然后使用Apache Common CSV解析器像这样工作CSV输入:
import java.io.*;
import java.util.*;
import org.apache.commons.csv.*;
public class YourCarCsvParser {
/** Column name for a car's ID. */
private static String CAR_ID = "carId";
public static void main(String[] args) throws Exception {
App app = new App();
for (String a : args) {
app.parse(new InputStreamReader(new FileInputStream(a)));
}
}
public List parse(Reader input) throws IOException {
// Initialize the list so you'll get an empty list not null if there is no CSV data.
List cars = new ArrayList<>();
CSVParser parser = CSVParser.parse(input, CSVFormat.RFC4180);
boolean hadHeaders = false;
for (CSVRecord record : parser) {
if (!hadHeaders) {
cars = makeCars(record);
hadHeaders = true;
}
else {
addSpeedsToCars(cars, record);
}
}
return cars;
}
private List makeCars(CSVRecord record) {
List cars = new ArrayList<>();
for (int i = 0; i < record.size(); i++) {
String field = record.get(i);
if (CAR_ID.equals(field)) {
cars.add(new Car(i, speedColumnFor(i)));
}
}
return cars;
}
private int speedColumnFor(int idColumn) {
// Assumes speed is always right of car ID.
return idColumn + 1;
}
private void addSpeedsToCars(List cars, CSVRecord record) {
for (int i = 0; i < record.size(); i++) {
for (Car c : cars) {
c.add(i, record.get(i));
}
}
}
}
这会将您的CSV转换为汽车列表,每个列表都包含其速度列表.
此代码基于一些假设,但您可以根据需要轻松修复它们:
> CSV中的列名称区分大小写.如果不是,请在检查CAR_ID时将equals更改为equalsIgnoreCase.>速度列紧靠汽车ID列:如果不是这种情况,请调整speedColumnFor方法以返回相应的列.当你没有固定的偏移量但需要查看标题时,这会变得有点棘手,例如,在看到ID列之后选择以下的mph标题.在这种情况下,您必须调整逻辑makeCars以记住ID列位置,并且只有在遇到mph列时才使用记住的ID列位置创建Car.>车辆ID是整数,就像您的示例数据一样.您也可以将它们更改为字符串.>速度是整数.如果需要浮点数,请在从字符串转换时将Integer.parseInt调整为Float.parseFloat.
最后
以上就是潇洒樱桃为你收集整理的java csv 标题行处理_java – 处理CSV文件中的重复标题名称的全部内容,希望文章能够帮你解决java csv 标题行处理_java – 处理CSV文件中的重复标题名称所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复