Как создать новые экземпляры классов на основе файла CSV

Допустим, у меня есть класс Car, и я пытаюсь импортировать большой набор данных для создания нескольких экземпляров «Car».

Мой CSV-файл выглядит так:

Производитель автомобиля, модель, цвет, владелец, MPG, номерной знак, страна происхождения, VIN и т. Д.

Дело в том, что в конструкторе должно быть много данных. Если их всего несколько, было бы не так уж плохо создать его вручную, написав Car FordFocus = new Car(Ford,Focus,Blue,John Doe,108-J1AZ,USA,194241-12e1...), но если у меня их сотни, есть ли способ импортировать все эти данные для создания классов?


person Will    schedule 09.12.2014    source источник
comment
Я голосую за закрытие, поскольку вам нужен инструмент для этого, и SO не просит рекомендаций по инструментам. Google для Java CSV, и вы должны найти некоторые инструменты самостоятельно. Попробуйте их, и если у вас есть проблемы с кодированием, опубликуйте свои конкретные проблемы.   -  person Dexygen    schedule 09.12.2014
comment
Инструмент? Вы имеете в виду библиотеку? Я пробовал Google, а также SO, прежде чем опубликовать, и ничего не нашел. Не могли бы вы дать ссылку?   -  person Will    schedule 09.12.2014


Ответы (3)


Как упоминает Джордж, вам нужен инструмент. Раньше для этого я использовал opencsv.

opencsv предоставляет вам три стратегии сопоставления (которые могут быть расширены) для сопоставления строки CSV с bean-компонентом. Самый простой - ColumnPositionMappingStrategy. Итак, если ваш формат CSV фиксированный, например строка заголовка выглядит так:

Производитель автомобиля, модель, цвет, владелец, MPG, номерной знак, страна происхождения, VIN и т. Д.

Этот фрагмент кода поможет вам. Я также использовал HeaderColumnNameTranslateMappingStrategy, который позволяет сопоставлять имена заголовков CSV с именами полей bean-компонентов, например. «Производитель автомобилей» -> Производитель автомобилей.

  CSVReader csvReader = new CSVReader(new FileReader(csvFile));
  ColumnPositionMappingStrategy<Car> strategy = new ColumnPositionMappingStrategy<Car>();
  strategy.setType(Car.class);
  String[] columns = new String[] {"CarManufacturer","Model","Color","Owner","MPG","LicensePlate","CountryOfOrigin","VIN"}; // the fields to bind do in your JavaBean
  strategy.setColumnMapping(columns);

  CsvToBean<Car> csv = new CsvToBean<Car>();
  List<Car> list = csv.parse(strategy, csvReader);

Самостоятельный пример программы можно найти здесь

person vsnyc    schedule 09.12.2014
comment
Ладно, думаю, я начинаю понимать. Допустим, в csv есть еще один столбец, определяющий имя класса. Допустим, есть класс fordFocus. Содержит ли переменная list все эти классы? Как мне теперь взаимодействовать с fordFocus? - person Will; 10.12.2014
comment
Ваш класс будет называться Car и будет иметь такие поля, как String CarManufacturer, String Model, String Color, String Owner и т. Д. Файл CSV будет содержать данные, по 1 строке на автомобиль, например. Ford, Focus, Red, John Doe ... Вы передадите этот файл CSV в CSVReader. Позже, когда вы выполните csv.parse (strategy, csvReader) - вы получите список объектов Car - person vsnyc; 10.12.2014
comment
Значит, вы обращаетесь к ним с помощью индексов? Например, если мне нужно поле модели fordFocus, я не могу вызвать fordFocus.model; Я бы назвал list [3] .model, если бы он был четвертым в списке? Спасибо! - person Will; 10.12.2014
comment
Было бы list.get(3).getModel(). Обычно вам нужен общедоступный метод получения, а поле model должно оставаться закрытым. - person vsnyc; 10.12.2014

Отражение - это возможность. Вы можете связать атрибут с позицией в вашем CSV-файле (столбец).

См., Например, установку атрибута с отражением: https://docs.oracle.com/javase/tutorial/reflect/member/fieldValues.html.

person Thierry    schedule 09.12.2014
comment
Заявление об этом размышлении или о чем-то еще в этом отношении вряд ли является ответом. - person Dexygen; 09.12.2014
comment
Я не уверен, что понимаю, как это работает. Вы можете привести мне пример? - person Will; 09.12.2014
comment
Я не согласен с @GeorgeJempty. Утверждение, что размышление - это возможность, - верный ответ; поскольку ОП, скорее всего, никогда не считал это. Кроме того, Тьерри кратко объяснил, как использовать отражение для достижения этой цели, и предоставил ссылку на учебное пособие по Java. ОП имеет достаточно информации для расследования. Тем не менее, ИМХО, размышление было бы моим последним выбором; особенно когда есть инструменты, которые могут делать это быстрее, чем использование отражения. - person hfontanez; 16.12.2014
comment
@hfontanez Когда я оставил свой комментарий, ответ состоял только из первой строки, а не из ссылки на учебник. В любом случае вы согласны с тем, что это плохой вариант, плюс ответ не показал (и до сих пор не показывает), как использовать отражение в этом конкретном случае использования. Я считаю, что простое указание (заполните пробел) - это возможность всегда является некачественным ответом. - person Dexygen; 16.12.2014

Вы можете читать CSV-файл построчно и создавать объект Car с помощью конструктора в цикле.

person Panther    schedule 09.12.2014
comment
Как я смогу получить доступ к объекту FordFocus после этого? Вы можете привести мне пример? - person Will; 09.12.2014