Заполнение объекта ошибкой возврата файла CSV

#java #servlets

#java #сервлеты

Вопрос:

У меня есть файл CSV, который содержит следующую информацию:

 Santa Catarina,Florianópolis,São José,Biguaçu,Palhoça
Rio grande do Sul,Porto alegre,,,
Paraná,Curitiba,Londrina,Ponta Grossa,
  

Все первые данные из каждой строки — это состояние, а следующие — города этого соответствующего состояния.

У меня есть два объекта, штат и город, штат (Estado) имеет название и ArrayList количество городов, а город (Cidade) имеет множество атрибутов.

Чтобы прочитать мой CSV, вот мой код:

 BufferedReader r = new BufferedReader(new FileReader("C:\Users\Pedro Sarkis\Desktop\ex3.csv"));

ArrayList<Estado> estados = new ArrayList<>();
ArrayList<Cidade> cidade = new ArrayList<>();

// String estados2[];
int i = 1;
String line = r.readLine();
try {
    while (line != null) {
        //  System.out.println("Line "   i   ": "   line);
        String[] campos = line.split(",");

        for (int j = 1; j < campos.length; j  ) {
            Cidade c = new Cidade();
            c.setNome(campos[j]);
            cidade.add(c);
        }

        Estado e = new Estado(campos[0], cidade);
        estados.add(e);

        cidade.clear();

        line = r.readLine();
        i  ;
    }
} finally {
    r.close();
}
  

Проблема в том, что я просто не могу ограничить города их соответствующими штатами.

Я тестировал использование .clear() для своего рода сброса моего списка после каждого while , но это не работает, потому что он сбрасывает все мои прошлые данные, и без использования .clear() все мои штаты получают все города.

Ответ №1:

Использование clear() в этом случае не сработает, поскольку предыдущие элементы в списке по-прежнему указывают на тот же объект. Таким образом, это также изменит значение предыдущих элементов. Измените свой код с

 cidade.clear();
  

Для

 cidade = new ArrayList<>();
  

Комментарии:

1. Если решение работает для вас, убедитесь, что вы проголосовали за ответ / отметили как решаемый.

Ответ №2:

У каждого экземпляра Estado должен быть совершенно новый список. Если вы передаете один и тот же объект List каждой конструкции Estado, все они используют один и тот же объект List. Вызов clear() не создает новый или другой объект списка, он просто удаляет элементы из того же объекта списка.

Есть два способа, которыми вы можете это сделать.

Первый подход: Вы можете изменить класс Estado, чтобы использовать объектно-ориентированную практику, известную как защитное копирование. Класс Estado скопировал бы аргумент List, указанный его конструктору, поэтому другой код не может изменить экземпляр Estado, изменив список. Таким образом, только вызывающие методы Estado могут изменять экземпляр Estado. Это позволяет нам сказать, что класс Estado инкапсулирует свои данные, имея исключительный контроль над своим собственным состоянием.

 public class Estado {
    private String state;

    private List<String> cities;

    public Estado(String state,
                  List<String> cities) {

        this.state = state;

        // Copying the List, so any later modifications cannot affect
        // this instance.
        this.cities = new ArrayList<>(cities);
    }
}
  

Второй подход: создайте новый список городов для каждой прочитанной строки.

 while (line != null) {

    String[] campos = line.split(","); 

    cidade = new ArrayList<>();

    // ...