Как прекратить запись данных в ArrayList?

Всем привет! Я изучаю Java и в пишу программку для сканера штрихкода.

Программа составлена так, что при вводе в консоль пользователем определенных команд происходит соответствующее действие.

Так например, при вводе в консоль слова "Склад" пользователю в консоль выводится список продуктов, которые есть в магазине.

Реализовано это так: Есть файл Warehouse.txt. В него предварительно заносится информация о продуктах в таком формате: Артикул, Наименование, Цена -> 486414, Хлеб, 40

Программа считывает информацию из файла, создает объекты класса Product и заносит данные в ArrayList. Код метода ниже:

public static void ListForToday(ArrayList<Product> products) throws IOException {
    BufferedReader storageReader = new BufferedReader(new FileReader ("C:\\Users\\Home PC\\IdeaProjects\\Barcode_reader\\src\\Warehouse.txt"));
    String mainLine = storageReader.readLine();
    while (true){
        String line = storageReader.readLine();
        if (line == null) break;
        String [] cells = line.split("\\s*,\\s*");
        int article = Integer.parseInt(cells[0]);
        String name = cells[1];
        int price = Integer.parseInt(cells[2]);
        products.add(new Product(article, name, price));
    }
}

Код, когда вводим слово "Склад" (находится в методе main):

if (stringScanner.equals("Склад") || stringScanner.equals("склад")) {
    System.out.println("Сегодня в продаже:");
    ListForToday(today);
    for (Product product : today) {
        System.out.println(product);
    }
}

И вроде как даже этот ужас работает, НО!

Если пользователь введет слово "Склад" ещё раз, то в ArrayList снова добавятся продукты из файла. И соответственно так при каждом вводе.

Как мне запретить запись из файла в ArrayList после того, как в него внесены данные в первый раз?

Не совсем понимаю как исправить этот баг.

Заранее благодарю!


Ответы (2 шт):

Автор решения: Alex Rudenko

Проблема состоит в том, что пользователь может ввести команду инициализации списка несколько раз, для её решения есть разные способы:

  1. принимать команду "склад" только один раз при запуске метода main - вне цикла
  2. проверять, пустой ли список перед обработкой команды "склад" -- можно дополнительно предложить пользователю варианты действий, если список непустой: прочитать заново, добавить в существующий список (как сделано сейчас), проигнорировать:
if ("склад".equalsIgnoreCase(stringScanner)) {
    if (!today.isEmpty()) {
        System.out.println("Список товаров непустой, 1) обновить список 2) добавить 3) отмена");
        int option = Integer.parseInt(scanner.nextLine());
        if (option < 3) {
            if (option == 1) today.clear();

            ListForToday(today);
        }
    }
}
  1. Можно ввести какой-то флажок, чтобы запомнить, что список уже был проинициализирован -- но такой подход наименее дружелюбный, так как не имеет смысла давать возможность какого-то действия, а затем возвращать ошибку, что оно запрещено.
boolean initialized = false;
if ("склад".equalsIgnoreCase(stringScanner)) {
    if (!initialized) {
        ListForToday(today);
        initialized = true;
    } else {
        System.out.println("Список уже был инициализирован");
    }
}
→ Ссылка
Автор решения: Perfect Voyage

Чтобы не добавлять заново те же объекты, можно спрашивать у List существует ли добавляемый экземпляр объекта. Для сравнения можно использовать лишь поле "Артикул".

 public static void ListForToday(ArrayList<Product> products) throws IOException {
    BufferedReader storageReader = new BufferedReader(new FileReader("C:\\Users\\Home PC\\IdeaProjects\\Barcode_reader\\src\\Warehouse.txt"));
    String mainLine = storageReader.readLine();
    // New
    ArrayList<Integer> articleList = new ArrayList<String>();
    if (products.size() != 0) {
        for (Product x : products) {
            articleList.add(x.getArticle());
            // Используйте инкапсуляцию! (гетеры и сетеры)
        }
    }
    //New
    while (true) {
        String line = storageReader.readLine();
        if (line == null) break;
        String[] cells = line.split("\\s*,\\s*");
        int article = Integer.parseInt(cells[0]);
        String name = cells[1];
        int price = Integer.parseInt(cells[2]);

        if (articleList.size() != 0) {
            articleList.contains(article) ? System.out.println("Объект уже существует")
                    :
                    products.add(new Product(article, name, price));
        }

    }
}

Честно признаюсь, я не знаю как будет работать анбоксинг в этой ситуации, но я думаю, должно сработать. Лучше хранить вашу коллекцию не в списке, а в множестве Set, переопределив поля equals и hashcode.

→ Ссылка