2017-10-06 4 views
1

J'ai txt fichier, chaque ligne contient deux mots, par exemple:Lire fichier par mot, Scanner

USA 321 
France 1009 
... 
Germany 902 

Comment puis-je lire ce fichier par mot dans la matrice à deux dimensions? J'ai:

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

Avez-vous d'utiliser un scanner pour la ligne? Sinon, utilisez 'String.split()' pour casser la ligne en mots. –

+0

Si vous devez utiliser un scanner pour la ligne, n'utilisez pas 'rowScanner.hasNextLine()'; il ne contient qu'une seule ligne. Utilisez 'hasNext()' (et 'next()') pour obtenir des mots individuels de la ligne. Aussi, si vous savez avec certitude que chaque ligne aura toujours exactement 2 mots, vous pouvez faire de votre structure une 'Liste '. – DodgyCodeException

Répondre

2

je le ferais comme ceci en supposant que votre code fonctionne

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

Cela prend la ligne en cours et il se divise en un espace. Ensuite, il crée une liste avec les deux éléments et ajoute à votre liste temps

1

Si vous voulez utiliser absolument 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]+")); 
      } 
     } 
1

Mon conseil est de toujours séparer des fonctionnalités différentes dans différentes fonctions. Le code devient plus facile à lire , plus facile à mantenir et réutilisable:

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

(utilisation List<String> comme MyData si vous avez besoin)

+0

D'accord avec vous. Dans votre code, je devrais ajouter une fonction pour lire seulement une MyData pour augmenter la maintabilité et la réutilisabilité – Tuco

1

Je suis un grand fan de scanner, mais dans ce cas, vous pouvez obtenir en lisant ligne par ligne et en utilisant String.split. Cela devient assez simple en utilisant les flux. Si vous voulez lire dans un tableau à deux dimensions, vous pouvez le faire:

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

Ou si vous voulez des listes imbriquées, vous pouvez le faire:

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