如何从文件中读取并将信息存储在链表(Java)中



我正在尝试读取一个文件,该文件包含创建手机的属性(如序列号、品牌、年份和价格(。然后,我想将信息存储在变量中,这样我就可以使用它的构造函数创建CellPhone对象。之后,我需要继续将这些手机对象添加到链表中,同时确保没有重复的对象(序列号相同的手机对象(。它适用于List为空的第一种情况,但是在我将第一个对象添加到List之后,会出现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

您也可以简单地查看以避免重复的

像这样声明手机

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");
}
}
}

在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);
}
}
} 

这个问题是因为在循环结束时,当您正在执行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();
}
}
}