String Array into arraylist?
I have a csv file with unknown amount of columns and row. The only thing I know is that each entry is separated by a comma. Can I use the split method to convert each line of the data into an array and then can I store that Array into an Arraylist. One of the things that concerns me is would I be able to rearrange the Arraylist alphabetically or nume开发者_如何学运维rically.
I would suggest using OpenCSV. If you just split on the comma separator, and you happen to have a single cell text containing a comma, but which is enclosed in double quotes to make it clear that it's a single cell, the split method won't work:
1, "I'm a single cell, with a comma", 2
3, hello, 4
OpenCSV will let you read each line as an array of Strings, handling this problem for you, and you can of course store each array inside a List. You will need a custom comparator to sort your list of lines. Search StackOverflow: the question of how to sort a list comes back twice a day here.
Yes, you can use:
String[] array = input.split("\",\"");
List<String> words = new ArrayList<String>(Arrays.asList(array))
Note that Arrays.asList(..)
also returns a List
, but you can't modify it.
Also note that the above split is on ","
, because CVSs usually look like this:
"foo","foo, bar"
Using split with simple comma is not a fool proof one. If your column data contains a comma, csv would be stored something like a,"b,x",c. In such case split would fail.
I'm not a regex expert maybe someone could write a EMBEDDED_COMMA_DETECTING_REGEX or GIYF.
String[] array = input.split(EMBEDDED_COMMA_DETECTING_REGEX);
List<String> words = new ArrayList<String>(Arrays.asList(array));
There are several questions here so I'll cover each point individually.
Can I use the split method convert each line of the data into an array
This would work as you expect in the naive case. However, it doesn't know anything about escaping; so if a comma is embedded within a field (and properly escaped, usually by double-quoting the whole field) the simple split won't do the job here and will chop the field in two.
If you know you'll never have to deal with embedded commas, then calling line.split(",")
is acceptable. The real solution however is to write a slightly more involved parse method which keeps track of quotes, and possibly backslash escapes etc.
...into an array than can I store that Array into an Arraylist
You certainly could have an ArrayList<String[]>
, but that doesn't strike me as particularly useful. A better approach would be to write a simple class for whatever it is the CSV lines are representing, and then create instances of that class when you're parsing each line. Something like this perhaps:
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);
}
Then you'd have a list of Orders, which more accurately represents what you have in the file (and in memory) than a list of string-arrays.
One of the things that concerns me is would I be able to rearrange the Arraylist according alphabetically or numerically?
Sure - the standard collections support a sort
method, into which you can pass an instance of Comparator
. This takes two instances of the object in the list, and decides which one comes before the other.
So following on from the above example, if you have a List<Order>
you can pass in whatever comparator you want to sort it, for example:
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);
精彩评论