我有一个包含未知数量的列和行的csv文件。我唯一知道的是每个条目都用逗号分隔。我可以使用split方法将每行数据转换为数组,然后将该数组存储到Arraylist中。我担心的一件事是我能够按字母顺序或数字方式重新排列Arraylist。
答案 0 :(得分:3)
是的,您可以使用:
String[] array = input.split("\",\"");
List<String> words = new ArrayList<String>(Arrays.asList(array))
请注意,Arrays.asList(..)
也会返回List
,但您无法对其进行修改。
另请注意,上面的拆分位于","
,因为CVS通常如下所示:
"foo","foo, bar"
答案 1 :(得分:3)
我建议使用OpenCSV。如果您只是在逗号分隔符上拆分,并且碰巧有一个包含逗号的单个单元格文本,但是用双引号括起来表明它是单个单元格,则拆分方法将不起作用:
1, "I'm a single cell, with a comma", 2
3, hello, 4
OpenCSV将允许您将每行读取为一个字符串数组,为您处理此问题,您当然可以将每个数组存储在List中。您将需要一个自定义比较器来对您的行列表进行排序。搜索StackOverflow:如何对列表进行排序的问题在这里每天返回两次。
答案 2 :(得分:1)
使用简单逗号分割并不是一个简单的逗号。如果您的列数据包含逗号,则csv将存储为类似“b,x”,c的内容。在这种情况下,拆分会失败。
我不是正则表达式专家,也许有人可以写一个EMBEDDED_COMMA_DETECTING_REGEX或GIYF。
String[] array = input.split(EMBEDDED_COMMA_DETECTING_REGEX);
List<String> words = new ArrayList<String>(Arrays.asList(array));
答案 3 :(得分:0)
这里有几个问题,所以我将逐一介绍每一点。
我可以使用split方法将每行数据转换为数组
这可以像你期望的那样天真地运作。但是,它对逃避没有任何了解;因此,如果一个逗号嵌入一个字段中(并且通常通过双引号整个字段进行适当的转义),那么简单拆分将不会在这里完成工作,并将字段切成两半。
如果您知道,您将永远不必处理嵌入式逗号,则可以接受调用line.split(",")
。然而,真正的解决方案是编写一个稍微更复杂的解析方法来跟踪引号,并可能反斜杠转义等。
...进入一个数组,而不是将该数组存储到Arraylist中
你当然可以拥有ArrayList<String[]>
,但这并不会让我觉得特别有用。更好的方法是为CSV线表示的任何内容编写一个简单的类,然后在解析每一行时创建该类的实例。也许是这样的事情:
public class Order {
private final int orderId;
private final String productName;
private final int quantity;
private final BigDecimal price;
// Plus constructor, getters etc.
}
private Order parseCsvLine(String line) {
String[] fields = line.split(",");
// TODO validation of input/error checking
final int orderId = Integer.parseInt(fields[0]);
final String productName = fields[1];
final int quantity = Integer.parseInt(fields[2]);
final BigDecimal price = new BigDecimal(fields[3]);
return new Order(orderId, productName, quantity, price);
}
然后你会得到一个Orders列表,它更准确地表示你在文件(和内存)中的是什么而不是字符串数组列表。
我担心的一件事是我可以按字母顺序还是按字母顺序重新排列Arraylist?
当然 - 标准集合支持sort
方法,您可以在其中传递Comparator
的实例。这将在列表中获取对象的两个实例,并决定哪一个在另一个之前。
所以继续上面的例子,如果你有一个List<Order>
,你可以传入你要对它进行排序的任何比较器,例如:
final Comparator<Order> quantityAsc = new Comparator<Order>() {
public int compare(Order o1, Order o2) {
return o2.quantity - o1.quantity; // smaller order comes before bigger one
}
}
final Comparator<Order> productDesc = new Comparator<Order>() {
public int compare(Order o1, Order o2) {
if (o2.productName == null) {
return o1.productName == null ? 0 : -1;
}
return o2.productName.compareTo(o1.productName);
}
}
final List<Order> orders = ...; // populated by parsing the CSV
final List<Order> ordersByQuantity = Collections.sort(orders, quantityAsc);
final List<Order> ordersByProductZToA = Collections.sort(orders, productDesc);