I am stuck with this problem, please help:
I want to read a txt file and put the content into an ArrayList, and the format is like this:
name Yoshida Shuhei
birthday 8-04-1961
phone 0123456789
email abc@123.com
medicalHistory None
address 12 X Street, Suburb,
NSW, Australia
address 13 Y Street, Suburb, VIC, Australia
name Kazuo Hirai
medicalHistory None
email xyz@123.com
phone 0987654321
birthday 26-11-1972
the file contains several patient records, and the record within each patient’s records block may occur in any order(e.g. the first patient’s name comes first, but the second patient’s address comes first), and all records are separated by blank lines.
My idea is, if the current line is not a blank line, begin to read the patient records and add them into a patient object, here’s my code:
public static ArrayList<Patient> getData(String fileName) {
try {
File file = new File(fileName);
Scanner reader = new Scanner(file);
ArrayList<Patient> recordList = new ArrayList<Patient>();
ArrayList<MedicalHistory> mhList = new ArrayList<MedicalHistory>();
int index = -1;
int mh_index = -1;
String s;
Patient p = null;
MedicalHistory mh = null;
boolean addressActive = false;
boolean mhActive = false;
while (reader.hasNext()) {
s = reader.nextLine();
Scanner line = new Scanner(s);
String cmd;
if (!s.trim().isEmpty()) {
cmd = line.next();
if (cmd.equalsIgnoreCase("name")) {
index++;
p = new Patient();
p.setName(line.nextLine());
recordList.add(index, p);
addressActive = false;
mhActive = false;
} else if (cmd.equalsIgnoreCase("address")) {
if (line.hasNext()) {
p.setAddress(line.nextLine().trim());
recordList.set(index, p);
}
addressActive = true;
mhActive = false;
} else if (cmd.equalsIgnoreCase("birthday")) {
p.setBirthday(line.nextLine());
recordList.set(index, p);
addressActive = false;
mhActive = false;
} else if (cmd.equalsIgnoreCase("email")) {
if (line.hasNext()) {
p.setEmail(line.nextLine());
recordList.set(index, p);
}
addressActive = false;
mhActive = false;
} else if (cmd.equalsIgnoreCase("phone")) {
if (line.hasNextInt()) {
p.setPhone(line.nextInt());
recordList.set(index, p);
}
addressActive = false;
mhActive = false;
} else if (cmd.equalsIgnoreCase("medicalHistory")) {
mh = new MedicalHistory();
//...parse the medicalHistory
addressActive = false;
mhActive = true;
} else if (addressActive) {
String address = p.getAddress() + " " + s.trim();
p.setAddress(address);
recordList.set(index, p);
} else if (mhActive) {
//to deal with multiple medical histories
} else
System.out.println("Error: no command:" + s);
}
}
reader.close();
return recordList;
} catch (Exception e) {
System.out.println("Error:- " + e.getMessage());
return null;
}
}
The problem is, my code can only handle when the name comes first; if the first non-empty line begins with other command(e.g. begins with address), there will be no new Patient() initialized for it, and the program will get an error…
So where exactly should I put the p = new Patient() in, the program to read the patient records no matter what the order of commands is, and then store the data in a Patient object?
Can anybody be able to improve my code and satisfy this condition? Thanks a lot!
I’d suggest that you read each block into a
HashMap<String,String>that maps each attribute to its value from the file. When the block is finished (that is, when you see a blank line or the end of the file) you can process the block in whatever particular order of attributes you need so as to properly create aPatientobject.Alternatively, with your current logic, you only need to change it a bit to do what you want:
Note that when you modify the current patient record (referenced by
p), you don’t need to set the element ofrecordListagain; it will be automatically updated, since it refers to the object already in the array list. With this, you don’t need theindexat all; you just add the new patient record to the end ofrecordListand keep modifying it as long as the input is still in the same block.