0

My code is reading through a txt file and then sorting it according to a field specified by the user and then outputting it on a table. Here's the code:

public static void sortByAtomicNumber() throws IOException
{
    File file = new File("Elements.txt");
    FileReader reader = new FileReader(file);
    BufferedReader i = new BufferedReader(reader);

    int lines = 0;
    while (i.readLine() != null) {
        lines++;
    }

    String[][] s = new String[lines][];
    String line;
    int index = 0;

    DefaultTableModel model = new DefaultTableModel(                                                                                      //Builds the table model
            new Object[]{"Name","Symbol","Atomic Number","Atomic Mass", "# of Valence Electrons"},
            0);

    while ((line = i.readLine()) != null && index < 10)
        s[index++] = line.split(",");

    for (int x = 0; x < s.length; x++)
    {
        for (int j = x + 1; j < s.length; ++j)
        {
            if (Integer.parseInt(s[x][2])>(Integer.parseInt(s[j][2])))
            {

                String[] temp = s[x];
                s[x] = s[j];
                s[j] = temp;
            }
        }
    }

    for(int x=0;x<s.length;++x){
        Object[]rows = {s[x][0], s[x][1], s[x][2], s[x][3], s[x][4]};                  //Puts information about the sorted elements into rows                                  
        model.addRow(rows);

    }
    JTable table = new JTable(model);                                                        
    JOptionPane.showMessageDialog(null, new JScrollPane(table));                           //Displays the table

}

Getting a java.lang.NullPointerException on this line when I run the program:

if (Integer.parseInt(s[x][2])>(Integer.parseInt(s[j][2])))

This is the data that is it searching through: https://i.stack.imgur.com/1vzR8.png

Not sure why this is happening, can anybody help me out?

W. Ahmed
  • 133
  • 1
  • 4
  • 14
  • Why was my closure reverted? It's a NPE question without any debugging performed. – Jeroen Vannevel Jan 11 '15 at 00:43
  • 1
    @JeroenVannevel - Because the question you referenced is not a duplicate of this. If you think this question lacked research effort, then the proper action is a downvote, not closure as a duplicate. – Ted Hopp Jan 11 '15 at 00:43
  • @TedHopp: the question I referenced is the canonical duplicate for NPE questions which people should look at before asking NPE-related questions. The OP has given no indication of knowing what a NPE is nor is any debugging done. – Jeroen Vannevel Jan 11 '15 at 00:44
  • 1
    @JeroenVannevel - It may be the canonical thread for explaining what an NPE is. So point OP to the question. But "canonical duplicate"? Not for questions that aren't duplicates. Reading that thread would not help OP. Also, I think OP is clear on what an NPE is, but perhaps ignorant of debugging techniques. I'd suggest that referring OP to some canonical question about how to debug (is there one?) would have been more useful. – Ted Hopp Jan 11 '15 at 00:49

1 Answers1

2

You are not actually reading the data into the array s. The problem is that in the process of counting lines, you have read to the end of the file and you are not resetting i back to the beginning. Thus every element of s is null. Thus the first attempt to read and parse a line (in the second loop) returns null and the body of the parsing loop is never executed.

You can either close and reopen the file, try using mark() and reset() on i, or (best) read into an ArrayList<String[]> instead of doing a two-pass read of the file.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • 1
    Voting down the question i may understand but voting down this clear answer i don't understand. Btw i would also suggest the author of the question to change his variable names... it helps a lot going through the code – MrVinz Jan 11 '15 at 00:44
  • @MrVinz - Thank you for your support. Random downvotes without explanation are the scourge of SO. – Ted Hopp Jan 11 '15 at 00:45
  • @TedHopp, The scourge of SO is also the excessive rush to duplication-removal, which this question also encountered. I've upvoted your answer BTW. –  Jan 11 '15 at 01:44
  • @TedHopp Can you show how you would use mark() and reset() on my code to fix the issue, can't seem to figure it out. – W. Ahmed Jan 11 '15 at 03:11
  • @W.Ahmed - Before starting the first read loop (that counts lines), simply call `i.mark(file.length())`. Then before starting the second loop, call `i.reset()`. Note the warning in [the docs for `mark(int)`](http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#mark%28int%29) about using this method for large argument values. That's why I recommend either close/open or simply reading into an `ArrayList`, where you don't need to know the number of lines ahead of time. – Ted Hopp Jan 11 '15 at 04:32
  • I did this, but I get a error on this line: i.reset() and it tells me java.io.IOException, Mark invalid (in java.io.BufferedReader) Any idea why it does this? – W. Ahmed Jan 12 '15 at 19:10
  • @W.Ahmed - I'm not sure, but possibly because the mark was not set properly. (Use `markSupported()` to test whether your reader supports `mark()`.) In any event, I'd strongly suggest that you avoid using mark/reset. It's cleaner to simply close the file and reopen it. And it's much cleaner to process the file in one pass rather than two; simply read each line, parse it, and add it to an `ArrayList` rather than adding it to a `String[][]`. That way you don't need to know the number of lines ahead of time. You can then extract a `String[][]` after the reading is done. – Ted Hopp Jan 12 '15 at 19:28
  • I ended up simply counting the lines on a different reader, then closing the file and then reopening it and it worked out how I wanted, I have also started reading into ArrayLists and I will definitely try to use it that way as-well, thanks for the help and the suggestion! – W. Ahmed Jan 13 '15 at 01:35