0

Solved adding if (line.isEmpty()) continue;

I need to read data from my text file and add this data into my ArrayList.

I see through debugger that the String[] words size is 1 which is "". That is why I get an exception :

Exception in thread "main" java.lang.NumberFormatException: For input string: ""
    at java.lang.NumberFormatException.forInputString(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)

My code is

List<Bill> list = new ArrayList<>();

try (BufferedReader reader = new BufferedReader(new FileReader("bill.txt"))) {
    String line;

    while ((line = reader.readLine()) != null) {
        String[] words = line.split(" ");
        Integer id = Integer.parseInt(words[0]);
        String venName = words[1];
        Double amount = Double.parseDouble(words[2]);
        LocalDate date = LocalDate.parse(words[3]);
        BillType bt = BillType.valueOf(words[4]);
        list.add(new Bill(venName, amount, date, bt, id));
    }
} catch(IOException e) {
    e.printStackTrace();
} 

In this assignment I cannot use File and Object input/output Stream.
Could you please help me fix this bug?

5
  • What does the file look like? Does it have all the things you are trying to read from it? Commented Feb 27, 2018 at 18:56
  • Check the contents of String line, does it contains space separated values? Commented Feb 27, 2018 at 18:56
  • 1
    Before the split, add a if (line.isEmpty()) continue; Commented Feb 27, 2018 at 18:57
  • 1
    Check words.length == 5 before you proceed with each iteration Commented Feb 27, 2018 at 19:11
  • 1
    Are you sure of the content of your original text file? Is there perhaps a "\n" or "\r" inserted that you can't see? You should really run a check on the size of words before you attempt to extract values from it with magic numbers Commented Feb 27, 2018 at 19:21

2 Answers 2

1

You could use streams from Java 8. I think that using pattern with groups is much more clear that simple split string:

private static final Pattern WORDS = Pattern.compile("(?<id>\\d+)\\s+(?<name>[^\\s]+)\\s+(?<amount>[^\\s]+)\\s+(?<date>[^\\s]+)\\s+(?<type>[^\\s]+)");

public static List<Bill> readBillFile(String fileName) throws IOException {
    return Files.lines(Paths.get(fileName))
                .map(WORDS::matcher)
                .filter(Matcher::matches)
                .map(matcher -> {
                    int id = Integer.parseInt(matcher.group("id"));
                    String venName = matcher.group("name");
                    double amount = Double.parseDouble(matcher.group("amount"));
                    LocalDate date = LocalDate.parse(matcher.group("date"));
                    BillType bt = BillType.valueOf(matcher.group("type"));
                    return new Bill(venName, amount, date, bt, id);
                })
                .collect(Collectors.toList());
}

Or you can just add check for total words to your code:

while ((line = reader.readLine()) != null) {
    String[] words = line.split(" ");

    if(words.length < 5)
        continue;

    // ...
}
Sign up to request clarification or add additional context in comments.

Comments

0

How about using the Scanner class?

import java.io.*;
import java.time.*;

try (Scanner reader = new Scanner (new File ("bill.txt"))) {
    while (reader.hasNextLine()) {
        reader.useDelimiter ("[ \t\n]");
        Integer id = reader.nextInt ();
        String venName = reader.next ();
        Double amount = reader.nextDouble ();
        LocalDate date = LocalDate.parse (reader.next ());
//      Don't know about BillType class
        String bt = reader.next ();
//      Don't have Bill.class
//      list.add(new Bill (venName, amount, date, bt, id));
    }
} catch (IOException e) {
    e.printStackTrace();
} 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.