Как читать из файла и хранить информацию в связанном списке (Java)?

Я пытаюсь прочитать файл, содержащий атрибуты для создания сотового телефона (такие как серийный номер, марка, год выпуска и цена). Затем я хочу сохранить информацию в переменных, чтобы я мог создавать объекты мобильного телефона с помощью его конструктора. После этого мне нужно продолжать добавлять эти объекты сотового телефона в связанный список, при этом следя за тем, чтобы не было дубликатов (объекты сотового телефона с одинаковым серийным номером). Он работает правильно для первого случая, когда список пуст, однако после того, как я добавил первый объект в список, возникает исключение NoSuchElementException. Что я сделал не так и как мне правильно прочитать файл? Любая помощь приветствуется.

Класс CellListUtilization:

// Method to read the file and store the information in the CellList
public static void processFile(Scanner sc1, CellList cl1) {
    String S = null;

    while(sc1.hasNext())
    {
        // First case where the list is empty
        if (cl1.getSize() == 0)
        {
            S = sc1.next();
            serialNum = Long.parseLong(S);
            S = sc1.next();
            brand = S;
            S = sc1.next();
            price = Double.parseDouble(S);
            S = sc1.next();
            year = Integer.parseInt(S);

            CellPhone c1 = new CellPhone(serialNum, brand, year, price);
            cl1.addToStart(c1);
        }
        else
        {
            serialNum = Long.parseLong(S);
            S = sc1.next();
            brand = S;
            S = sc1.next();
            price = Double.parseDouble(S);
            S = sc1.next();
            year = Integer.parseInt(S);

            if (!(cl1.contains(serialNum)))
            {
                CellPhone c2 = new CellPhone(serialNum, brand, year, price);
                cl1.addToStart(c2);
            }
        }
        S = sc1.next();
    }
}

Файл, который я пытаюсь прочитать:

3890909 Samsung         857.28 2015
2787985 Acer            572.20 2013
4900088 LG              232.99 2017
1989000 Nokia           237.24 2006
0089076 Sharp           564.22 2009
2887685 Motorola        569.28 2012
7559090 Pansonic        290.90 2005
2887460 Siemens         457.28 2009
2887685 Apple           969.28 2018
6699001 Lenovo          237.29 2012
9675654 Nokia           388.00 2009
1119002 Motorola        457.28 2008
5000882 Apple           977.27 2016
8888902 Samsung         810.35 2018
5890779 Motorola        457.28 2007
7333403 BenQ            659.00 2009
2999900 Siemens         457.28 2006
6987612 HTC             577.25 2009
8888902 BenQ            410.35 2009
8006832 Motorola        423.22 2008
5555902 SonyEricsson    177.11 2007
9873330 Nokia           677.90 2010
8888902 BenQ            410.35 2009
5909887 Apple           726.99 2017
2389076 BlackBerry      564.22 2010
1119000 SonyEricsson    347.94 2009

person Joey    schedule 29.11.2018    source источник


Ответы (3)


Ваш код пытается найти элемент на следующей строке, прежде чем условие цикла while сможет подтвердить, что строка существует. Если файл содержит 4 столбца данных в строке, вы не должны вызывать sc1.next() более 4 раз в одном цикле, чтобы избежать NoSuchElementException.

Перемещение последнего вызова sc1.next() из конца цикла while в начало блока else должно решить проблему.

while(sc1.hasNext())
{
    // First case where the list is empty
    if (cl1.getSize() == 0)
    {
        S = sc1.next();
        serialNum = Long.parseLong(S);
        S = sc1.next();
        brand = S;
        S = sc1.next();
        price = Double.parseDouble(S);
        S = sc1.next();
        year = Integer.parseInt(S);

        CellPhone c1 = new CellPhone(serialNum, brand, year, price);
        cl1.addToStart(c1);
    }
    else
    {
        S = sc1.next();
        serialNum = Long.parseLong(S);
        S = sc1.next();
        brand = S;
        S = sc1.next();
        price = Double.parseDouble(S);
        S = sc1.next();
        year = Integer.parseInt(S);

        if (!(cl1.contains(serialNum)))
        {
            CellPhone c2 = new CellPhone(serialNum, brand, year, price);
            cl1.addToStart(c2);
        }
    }
} 
person Peba    schedule 29.11.2018
comment
Да, это имеет абсолютный смысл! Это решило проблему, большое спасибо!! :) - person Joey; 29.11.2018
comment
@Джои Рад, что смог помочь. Я вижу, что часть вашего кода не соответствует соглашениям о кодировании Java, я рекомендую вам немного прочитать об этом, чтобы сделать ваш код более понятным для других. - person Peba; 29.11.2018

Вы можете просто посмотреть на это, чтобы избежать дубликатов.

Объявить CellPhone следующим образом

public class CellPhone {

    private Long serialNumber;
    private String brand;
    private Integer year;
    private Double price;

    CellPhone(Long serialNumber, String brand, int year, double price) {
        this.serialNumber = serialNumber;
        this.brand = brand;
        this.year = year;
        this.price = price;
    }

    public Long getSerialNumber() {
        return serialNumber;
    }

    public void setSerialNumber(Long serialNumber) {
        this.serialNumber = serialNumber;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Integer getYear() {
        return year;
    }

    public void setYear(Integer year) {
        this.year = year;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    @Override
    public int hashCode() {
        return serialNumber.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof CellPhone))
            return false;

        CellPhone mdc = (CellPhone) obj;
        return mdc.serialNumber.equals(serialNumber);
    }
}

И тогда ваш класс нужно изменить так

public class ListPractice {


    public static void main(String[] args) throws IOException {
        //Creating BufferedReader object to read the input text file
        Scanner scanner = new Scanner(new File("E:\\Projects\\JavaBasics\\src\\data.txt"));
        LinkedList<CellPhone> cellPhones = new LinkedList<>();
        processFile(scanner, cellPhones);

        Iterator i = cellPhones.iterator();
        while (i.hasNext()) {
            CellPhone phone = (CellPhone) i.next();
            System.out.println(phone.getSerialNumber());
        }
    }

    public static void processFile(Scanner sc1, LinkedList<CellPhone> cl1) {
        String S = null;

        while (sc1.hasNext()) {

            S = sc1.next();
            Long serialNum = Long.parseLong(S.trim());
            S = sc1.next();
            String brand = S.trim();
            S = sc1.next();
            double price = Double.parseDouble(S.trim());
            S = sc1.next();
            int year = Integer.parseInt(S.trim());

            CellPhone c1 = new CellPhone(serialNum, brand, year, price);
            if (!cl1.contains(c1))
                cl1.add(c1);
           // else System.out.println("Duplicate data");
        }
    }

}
person flopcoder    schedule 29.11.2018

Эта проблема связана с тем, что в конце, пока вы делаете sc1.next(), но читать нечего, это происходит в конце цикла, поэтому вы можете добавить if для решения вашей проблемы.

  public static void processFile(Scanner sc1, CellList cl1) {
        String S = null;

        while(sc1.hasNext())
        {
            // First case where the list is empty
            if (cl1.getSize() == 0)
            {
                S = sc1.next();
                serialNum = Long.parseLong(S);
                S = sc1.next();
                brand = S;
                S = sc1.next();
                price = Double.parseDouble(S);
                S = sc1.next();
                year = Integer.parseInt(S);

                CellPhone c1 = new CellPhone(serialNum, brand, year, price);
                cl1.addToStart(c1);
            }
            else
            {
                serialNum = Long.parseLong(S);
                S = sc1.next();
                brand = S;
                S = sc1.next();
                price = Double.parseDouble(S);
                S = sc1.next();
                year = Integer.parseInt(S);

                if (!(cl1.contains(serialNum)))
                {
                    CellPhone c2 = new CellPhone(serialNum, brand, year, price);
                    cl1.addToStart(c2);
                }
            }
             if(sc1.hasNext()) { 
             S =sc1.next();
            }
        }
    }
person Jorge Arguedas Arrieta    schedule 29.11.2018