字符串数组到arraylist?

时间:2011-08-30 07:45:08

标签: java csv arraylist

我有一个包含未知数量的列和行的csv文件。我唯一知道的是每个条目都用逗号分隔。我可以使用split方法将每行数据转换为数组,然后将该数组存储到Arraylist中。我担心的一件事是我能够按字母顺序或数字方式重新排列Arraylist。

4 个答案:

答案 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);