Reputation: 462
I am trying to read Strings from a file which are separated with a semicolon and put them in an arrayList. Here is my code:
public ArrayList<String> readFile() throws IOException{
lines=new ArrayList<String>();
BufferedReader reader = new BufferedReader(new FileReader("D:\\input.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
inputs = line.split(";");
}
reader.close();
for (String in : inputs) {
lines.add(in);
}
System.out.println(lines.size());
return lines;
}
When I run it, the size of the ArrayList returned is a very small number. The expected number is bigger.
Any suggestions?
Upvotes: 2
Views: 3117
Reputation: 69249
Well... First answering your question: lines.size()
is very small at the end of the program, because you first loop through all lines via readLine()
, and overwrite the value of readLine().split(";")
on inputs
on every iteration. Then just before your program ends, you add the contents of your last line, split up by ';', to lines
.
The solution would be to move the for
-loop that adds the split up lines to the loop, inside the while
loop.
Also observe that you could call lines.addAll(inputs)
to add all of them to lines
, then you do not need to loop over them, which essentially clutters your code as it is an unneccessary operation.
This could also be done in the following way in Java 8:
try {
List<String> lines = new BufferedReader(new FileReader("D:\\input.txt")).lines().collect(Collectors.toList());
} catch (FileNotFoundException ex) {
Logger.getLogger(MultiMapJava8.class.getName()).log(Level.SEVERE, null, ex);
}
So assuming you have a reader
available, it is even as simple as:
List<String> lines = reader.lines().collect(Collectors.toList());
Explanation:
BufferedReader
instance.lines()
on it to get a Stream<String>
. Nb. Streams is a really nice new concept of Java 8, read up about it!Stream<String>
into a List<String>
, which is done by calling collect(Collectors.toList())
on the stream.And just now I realized that you split the lines itself on a ;
aswell, so glad we have a Stream<String>
, the code now would be:
BufferedReader reader = new BufferedReader(new FileReader("D:\\input.txt"));
List<String> lines = reader.lines()
.flatMap(line -> Arrays.stream(line.split(";")))
.collect(Collectors.toList());
The extra step added is flatMap(line -> Arrays.stream(line.split(";")))
, this contains a lambda expression from String
to a Stream<String>
, where the stream has been created by creating a stream from line.split(";")
, which returned a String[]
.
All flatMap(...)
does is add those resulted elements back in the original Stream<String>
, so it is a kind of expension method.
Upvotes: 3
Reputation: 4923
Add the iteration of String list inside the loop,before it was outside due to which only last entry was inserted into the list
while ((line = reader.readLine()) != null) {
inputs = line.split(";");
for (String in : inputs) {
lines.add(in);
}
}
Upvotes: 1
Reputation: 18123
You overwrite inputs
on every iteration and end up with the last line when exiting the loop. More like
while ((line = reader.readLine()) != null) {
inputs = line.split(";");
for (String in : inputs) {
lines.add(in);
}
}
Upvotes: 1
Reputation: 328568
You keep overwriting the content of inputs
- so once you reach the second loop, it only contains the data on the last line of your file.
So you should be using something like this instead:
while ((line = reader.readLine()) != null) {
Collections.addAll(lines, line.split(";"));
}
And you also improve your program:
Files
helper methods:So it could look like:
public List<String> readFile() throws IOException {
List<String> lines = Files.readAllLines(Paths.get("D:/input.txt"));
List<String> tokens = new ArrayList<>();
for (String line : lines) {
Collections.addAll(tokens, line.split(";"));
}
return tokens;
}
Upvotes: 3