Reputation: 57
So i have this dat file (txt file) that has one state and one zipcode each of a country. In this dat file i have a semi semicolon that separates the strings for each line and the integers for each line. I am also using an interface and a main class for this but this is the class that should do most of the work. And down below is the method.
PS: I have tried to find other questions on this site that already answers my Q but non of them actually helped!
This is what the dat file has :
75242;Uppsala
90325;Umeå
96133;Boden
23642;Höllviken
35243;Växjö
51000;Jönköping
72211;Västerås
My problem is that i cannot find a way to keep the integers or the strings in the arrays in the way that i want them to work. Have tried to read only integers and only strings but that didn't work. Do also note that i have tried to read every line and then every char in the dat file to try to put the values in their own arrays. Also tried to shift them by using if'ments and saying "if(Character.is..)". In the method below i'm only trying to capture the integers.
Was also thinking that due to the semicolon i should use something like "Character.is...." to check for that and then go over from reading ch/string to int. But want to take one step at the time or else i won't get anything done!
public void read() {
try {
ArrayList<Integer> itemArr = new ArrayList<Integer>();
ArrayList<String> descArr = new ArrayList<String>();
FileReader file = new FileReader("C:\\Users\\me\\Desktop\\places.dat");
BufferedReader r = new BufferedReader(file);
int r1;
while ((r.readLine()) != null) {
while ((r1 = r.read()) != -1) {
char ch = (char) r1;
if (Character.isDigit(ch)) {
itemArr.add(r.read());
}
}
}
} catch (IOException e) {
}
}
This is what is expected : They are also sorted, but i can handle that as long as i can figure out of how to store the correctly in each of their own arrays.
23642 Höllviken
35243 Växjö
51000 Jönköping
72211 Västerås
75242 Uppsala
90325 Umeå
96133 Boden
Thanks for all the comments, really does help.
Upvotes: 1
Views: 92
Reputation: 727
Using two lists is overkill. If you know that each zipcode is related to each country, you should create objects to store them, then put those objects into a list.
public class MyLocation {
private int zipcode;
private String country;
public MyLocation(int zipcode, String country) {
this.zipcode = zipcode;
this.country = country;
}
public int getZipcode() {
return zipcode;
}
public String getCountry() {
return country;
}
}
Also, you have a delimited data set so you should take advantage of that! Use String.split()
and split on that semicolon to obtain an array with both of your elements ready for extraction.
ArrayList<MyLocation> locations = new ArrayList<>();
try {
FileReader file = new FileReader("C:\\Users\\me\\Desktop\\places.dat");
Bufferedreader r = new BufferedReader(file);
try {
String line;
String[] lineValues;
while ((line = r.readLine()) != null) {
lineValues = line.split(";");
MyLocation location = new MyLocation(Integer.valueOf(lineValues[0]), lineValues[1]);
locations.add(location);
}
} finally {
r.close();
}
} catch (IOException e) {
e.printStackTrace();
}
Also, it's a good idea to close the resource when you are done using it. I've edited my code to demonstrate one way to do this.
As others have mentioned if you want sorting you will need to also implement Comparable
but that is pretty straightforward.
Upvotes: 0
Reputation: 3947
I suggest you to create a new class, for example where to store the number and the name:
class NumberName {
Integer number;
String name;
// constructor, setter, getter
}
Then when reading from file, you put them in a list:
FileReader file = new FileReader("C:\\Users\\me\\Desktop\\places.dat");
BufferedReader r = new BufferedReader(file);
String line;
List<NumberName> list = new ArrayList<>();
while ((line = r.readLine()) != null) {
String[] split = line.split(";");
list.add(new NumberName(Integer.parseInt(split[0]), split[1]));
}
Then sorting becomes easy as:
list.sort(Comparator.comparingInt(NumberName::getNumber)); // by number
list.sort(Comparator.comparing(NumberName::getName)); // by name
list.sort(Comparator.comparing(NumberName::getNumber).thenComparing(NumberName::getName)); // by number then by name
Upvotes: 0
Reputation: 400
You can use split function and split it using ";" as .dat file has ; between zipcode and string. If you want zipcode to be integer, you can parse the parts[0] as below to give you an idea/
FileReader file = new FileReader("C:\\Users\\me\\Desktop\\places.dat");
BufferedReader r = new BufferedReader(file);
String st;
while ((st = br.readLine()) != null) {
String[] parts = st.split[";"]
parts[0] // will have zipcode
parts[1] // will have other part
}
Upvotes: 0
Reputation: 15423
You can change your logic to the following :
String currLine;
while ((currLine = r.readLine()) != null) {
if (currLine.trim().length() > 0) {
String[] split = currLine.split(";");
itemArr.add(Integer.parseInt(split[0]));
descArr.add(split[1]);
}
}
Here we split each line(currLine) based on ;
and store it into the array split
. Now the 0th index will contain the number and the 1st index will contain the String.
To add it the the itemArr
you need to parse it to an int
. Also note that if the line is empty it is skipped. Sorting it is also pretty straight-forward now.
Upvotes: 1