String Array в arraylist? - PullRequest
       4

String Array в arraylist?

1 голос
/ 30 августа 2011

У меня есть CSV-файл с неизвестным количеством столбцов и строк. Единственное, что я знаю, это то, что каждая запись разделяется запятой. Можно ли использовать метод split для преобразования каждой строки данных в массив, а затем сохранить этот массив в Arraylist. Одна из вещей, которая меня беспокоит, - смогу ли я переставить Arraylist в алфавитном или числовом формате.

Ответы [ 4 ]

3 голосов
/ 30 августа 2011

Я бы предложил использовать OpenCSV . Если вы просто разбили разделитель запятых и у вас есть текст в одну ячейку, содержащий запятую, но заключенный в двойные кавычки, чтобы было ясно, что это одна ячейка, метод split не будет работать:

1, "I'm a single cell, with a comma", 2
3, hello, 4

OpenCSV позволит вам читать каждую строку как массив строк, решая эту проблему для вас, и вы, конечно, можете хранить каждый массив внутри списка. Вам понадобится собственный компаратор для сортировки списка строк. Поиск StackOverflow: вопрос о том, как сортировать список, возвращается сюда два раза в день.

3 голосов
/ 30 августа 2011

Да, вы можете использовать:

String[] array = input.split("\",\"");
List<String> words = new ArrayList<String>(Arrays.asList(array))

Обратите внимание, что Arrays.asList(..) также возвращает List, но вы не можете изменить его.Также обратите внимание, что вышеприведенный сплит на ",", потому что CVS обычно выглядят так:

"foo","foo, bar"
1 голос
/ 30 августа 2011

Использование split с простой запятой не является надежным. Если данные вашего столбца содержат запятую, CSV будет храниться что-то вроде a, "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));
0 голосов
/ 30 августа 2011

Здесь есть несколько вопросов, поэтому я рассмотрю каждую точку отдельно.

Могу ли я использовать метод разбиения, чтобы преобразовать каждую строку данных в массив

Это будет работать, как вы ожидаете, в наивном случае.Тем не менее, он ничего не знает о побеге;так что если запятая вставлена ​​в поле (и правильно экранирована, обычно заключая двойные кавычки во все поле), то простое разбиение не выполнит эту работу и разделит поле на две части.

Если вы знайте вам никогда не придется иметь дело со встроенными запятыми, тогда вызов 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);
}

Тогда у вас будет список заказов, который более точно представляет , что у вас есть в файле (и в памяти), чем список строк-arrays.


Одна из вещей, которая меня беспокоит, это то, смогу ли я переставить 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...