ggeo
ggeo

Reputation: 462

Reading strings from a file to an arraylist with java

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

Answers (4)

skiwi
skiwi

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:

  1. Obtain a BufferedReader instance.
  2. Call lines() on it to get a Stream<String>. Nb. Streams is a really nice new concept of Java 8, read up about it!
  3. Collect the 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

Kick
Kick

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

Smutje
Smutje

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

assylias
assylias

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:

  • by using the Files helper methods:
  • by naming the variables more appropriately (lines really contains the tokens on each line)
  • return an interface instead of a concrete implementation (List vs ArrayList).

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

Related Questions