2017-10-06 4 views
1

Ich habe txt-Datei, die jede Zeile zwei Worte enthält, zum Beispiel:liest Datei durch Wort, Scanner

USA 321 
France 1009 
... 
Germany 902 

Wie kann ich diese Datei durch das Wort in einem zweidimensionalen Array lesen? Ich habe:

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()) { 
     ... 
    } 
} 
+0

Müssen Sie einen Scanner verwenden für die Reihe? Wenn nicht, verwenden Sie 'String.split()', um die Zeile in Wörter aufzuteilen. –

+0

Wenn Sie einen Scanner für die Zeile verwenden müssen, verwenden Sie nicht rowScanner.hasNextLine() '; es enthält nur eine Zeile. Verwenden Sie 'hasNext()' (und 'next()'), um einzelne Wörter aus der Zeile zu erhalten. Wenn Sie sicher sind, dass jede Zeile immer genau 2 Wörter haben wird, können Sie Ihre Struktur als "Liste " definieren. – DodgyCodeException

Antwort

2

ich es wie folgt vorausgesetzt, Ihr Code tun würde, funktioniert

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])); 
} 

Dies nimmt die aktuelle Zeile und spaltet sie in einem Leerzeichen. Danach erstellt er eine Liste mit den beiden Elementen und fügt es zu einem temps Liste

1

Wenn Sie unbedingt Scanner verwenden möchten:

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]+")); 
      } 
     } 
1

Mein Rat ist, unterschiedliche Funktionalitäten in verschiedenen Funktionen immer getrennt. Der Code wird einfacher zu lesen, einfacher zu mantain und wiederverwendbar:

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; 
} 

(Verwenden List<String> als MyData, wenn Sie benötigen)

+0

Stimmen Sie mit Ihnen überein. In Ihrem Code sollte ich eine Funktion hinzufügen, um nur eine MyData zu lesen, um die Wartbarkeit und Wiederverwendbarkeit zu erhöhen – Tuco

1

ich ein großer Fan von Scanner ist, aber In diesem Fall können Sie Zeile für Zeile lesen und String.split verwenden. Dies wird mit Streams sehr einfach. Wenn Sie in eine zweidimensionale Anordnung lesen möchten, können Sie dies tun:

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

Oder wenn Sie verschachtelte Listen möchten, können Sie dies tun:

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); 
    } 
Verwandte Themen