Adrian
Adrian

Reputation: 43

Read file by word, Scanner

I have txt file, which each row contains two words, for example:

USA 321
France 1009
...
Germany 902

How can I read this file by word in two-dimensional array? I have:

List<List<String>> temps = new ArrayList<>();
Scanner dataScanner = new Scanner(dataFile);

while (dataScanner.hasNextLine()) {
    Scanner rowScanner = new Scanner(dataScanner.nextLine());
    temps.add(new ArrayList<>(2));

    while (rowScanner.hasNextLine()) {
        ...
    }
}

Upvotes: 1

Views: 1349

Answers (4)

Stuart Marks
Stuart Marks

Reputation: 132390

I'm a big fan of Scanner, but in this case you can get by reading line-by-line and using String.split. This becomes quite simple using streams. If you want to read into a two-dimensional array, you can do this:

    try (Stream<String> lines = Files.lines(Paths.get(FILENAME), UTF_8)) {
        String[][] result = lines.map(s -> s.split("\\s+"))
                                 .toArray(String[][]::new);
    }

Or if you want nested Lists, you can do this:

    try (Stream<String> lines = Files.lines(Paths.get(FILENAME), UTF_8)) {
        List<List<String>> result = lines.map(s -> s.split("\\s+"))
                                         .map(Arrays::asList)
                                         .collect(toList());
        System.out.println(result);
    }

Upvotes: 1

Oneiros
Oneiros

Reputation: 4378

My advice is to ALWAYS separate different functionalities in different functions. The code becomes easier to read, easier to mantain and reusable:

public static List<String> readFileLineByLine(String file) {
   List<String> lines = new ArrayList<>();
   Scanner scanner = new Scanner(file);
   while (scanner.hasNextLine()) {
      temps.add(scanner.nextLine());
   }
   return lines;
}

public static List<MyData> parseLines(List<String> lines) {
   List<MyData> list = new ArrayList<>();
   for (String line : lines) {
      String[] data = line.split(" ");
      list.add(new MyData(data[0], data[1]));
   }
   return list;
}

(Use List<String> as MyData if you need to)

Upvotes: 1

Tuco
Tuco

Reputation: 513

If you want absolutely use Scanner :

List<List<String>> temps = new ArrayList<>();
        Scanner dataScanner = new Scanner("a b\nc d\ne f\n");

        while (dataScanner.hasNextLine()) {
            Scanner rowScanner = new Scanner(dataScanner.nextLine());
            List<String> datas=new ArrayList<>(2);
            temps.add(datas);

            while (rowScanner.hasNext("[^\\s]+")) {
                datas.add(rowScanner.next("[^\\s]+"));
            }
        }

Upvotes: 1

Dinh
Dinh

Reputation: 779

I would do it like this assuming your code works

List<List<String>> temps = new ArrayList<>();
Scanner dataScanner = new Scanner(dataFile);

while (dataScanner.hasNextLine()) {
    String[] data = dataScanner.nextLine().split(" ");
    temps.add(new ArrayList<>(Arrays.asList(data[0],data[1]));
}

This takes the current line and splits it at a space character. Afterwards it creates a list with the two elements and adds it to your temps list

Upvotes: 2

Related Questions