web-dev-qa-db-fra.com

Lire un fichier séparé par une tabulation et mettre les mots dans une liste de tableaux

Je fais un exercice d'auto-apprentissage pour m'aider à mieux comprendre Java, mais je suis bloqué à cette question. J'ai le fichier txt suivant:

Name  Hobby 
Susy  eat fish 
Anna  gardening
Billy bowling with friends

Remarque: le nom et le passe-temps sont séparés par des tabulations

Quelle est la meilleure façon de lire toute la ligne et de la mettre en liste (nom, passe-temps). La partie délicate est que

eat fish or bowling with friends

a des espaces blancs et il doit être placé sous un tableau et évidemment je ne peux pas le coder en dur. Voici mon code actuel:

 public void openFile(){
            try{
                FileInputStream fstream = new    FileInputStream("textfile.txt");
          // use DataInputStream to read binary NOT text
          BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
          ArrayList<String> names = new ArrayList<String>();
          ArrayList<String> hobbies = new ArrayList<String>();
          String lineJustFetched;
          while ((lineJustFetched = br.readLine()) != null)   {
          String[] tokens = lineJustFetched.split(" \t");

J'ai une erreur:

Java.lang.StringIndexOutOfBoundsException: index de chaîne hors limites: -1

Je soupçonne que compter l’index n’est pas très utile sur un onglet. Une idée?

10
user2891092

Bon, vous devez faire la recette ci-dessous: 

  1. Créer une BufferedReader 
  2. Créer un ArrayList<String>
  3. Commencez à lire les données dans une variable String nommée lineJustFetched
  4. Divisez la String en appelant lineJustFetched.split("\t"); 
  5. Itérer sur le String[] produit. Vérifiez si le jeton que vous souhaitez entrer dans la variable ArrayList n'est pas "" 
  6. Sinon, ajoutez le mot à la ArrayList 

Vous indiquez que vous devez fractionner selon les valeurs de \t afin que les espaces ne soient pas un problème. 

SSCCE 

import Java.io.BufferedReader;
import Java.io.FileReader;
import Java.util.ArrayList;

public class WordsInArray {
    public static void main(String[] args) {
        try{
            BufferedReader buf = new BufferedReader(new FileReader("/home/little/Downloads/test"));
            ArrayList<String> words = new ArrayList<>();
            String lineJustFetched = null;
            String[] wordsArray;

            while(true){
                lineJustFetched = buf.readLine();
                if(lineJustFetched == null){  
                    break; 
                }else{
                    wordsArray = lineJustFetched.split("\t");
                    for(String each : wordsArray){
                        if(!"".equals(each)){
                            words.add(each);
                        }
                    }
                }
            }

            for(String each : words){
                System.out.println(each);
            }

            buf.close();

        }catch(Exception e){
            e.printStackTrace();
        }
    }
}    

Sortie  

John
likes to play tennis
Sherlock
likes to solve crime
9
Little Child

Si vous avez séparé la colonne Nom et Loisir avec l'onglet \t, vous devriez faire quelque chose comme ceci (et n'oubliez pas de fermer l'analyse à la fin):

public void readFile() throws FileNotFoundException{
    Scanner scan = new Scanner(new File("D://a.txt"));
    ArrayList<String> names = new ArrayList<String>();
    ArrayList<String> hobbies = new ArrayList<String>();

    while(scan.hasNext()){
        String curLine = scan.nextLine();
        String[] splitted = curLine.split("\t");
        String name = splitted[0].trim();
        String hobby = splitted[1].trim();
        if(!"Name".equals(name)){
            names.add(name);
        }
        if(!"Hobby".equals(hobby)){
            hobbies.add(hobby);
        }
    }
    System.out.println(names);
    System.out.println(hobbies);
    scan.close();
}
2
united

Pour d'autres encore trébucher sur cela. 

À l'aide de Stream API (Java 8), vous pouvez le faire 

Ceci montre 

  • Méthode de filtrage pour filtrer le premier élément d'en-tête de la liste
  • méthode map pour mapper chaque élément du flux en un autre élément pour le nouveau flux 
package com.bhavya.stackoverflow.examples.q19575308;

import Java.io.BufferedReader;
import Java.io.InputStream;
import Java.io.InputStreamReader;
import Java.util.Arrays;
import Java.util.HashMap;
import Java.util.function.Predicate;

/**
 * Java 8 Stream API to handle file reading.
 *
 * @author bhavya.work
 */
public class StreamTests {
  public static void main(String[] args) {
    try {
      InputStream fileInputStream;
      BufferedReader bufferedReader;
      final String filepathInSamePackage = "textfile.txt";
      //filter predicate
      Predicate<String> filterFirstLine =
          line -> !(
              "Name".equals(line.split("\t", -1)[0])
                  && "Hobby".equals(line.split("\t", -1)[1])
          );

      //Implementation 1 returns Arrays as asked.

      System.out.println("==ArrayList==");
      fileInputStream = StreamTests.class.getResourceAsStream(filepathInSamePackage);
      bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));

      bufferedReader
          .lines()
          .filter(filterFirstLine)
          .map(s -> {
            String[] splitStrings = s.split("\t", -1);
            return Arrays.asList(splitStrings);
          }).forEach(System.out::println);

      //Implementation 2 returns HashMap as another example

      fileInputStream = StreamTests.class.getResourceAsStream(filepathInSamePackage);    
      bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
      System.out.println("\n==HashMap==");

      bufferedReader
          .lines()
          .filter(filterFirstLine)
          .map(s -> {
            String[] splitStrings = s.split("\t", -1);
            HashMap<String, String> stringStringMap = new HashMap<>();
            stringStringMap.put(splitStrings[0], splitStrings[1]);
            return stringStringMap;
          }).forEach(System.out::println);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Et la sortie

==ArrayList==
[Susy, eat fish]
[Anna, gardening]
[Billy, bowling with friends]

==HashMap==
{Susy=eat fish}
{Anna=gardening}
{Billy=bowling with friends} 
1
bhavya.work

Vous devriez essayer la bibliothèque commons-lang . Parmi beaucoup d'autres choses utiles, vous pouvez diviser une chaîne à l'aide d'un délimiteur:

String x="Billy bowling with friends";

String y[]=StringUtils.split(x, '\t');

En supposant qu'il y ait un onglet entre Billy et bowling,

  • y [0] contient "Billy"
  • y 1 contient "bowling avec des amis"
0
windjammer

Pour les références futures lorsque vous analysez l'onglet, il existe un délimiteur tel que "\ t" pour l'onglet. Utilisez-le plutôt que .split ("")

En outre, lorsque votre erreur est renvoyée car cela signifie qu'aucun caractère n'est trouvé, d'où le -1, donc lorsque vous essayez de le stocker dans un tableau ... -1 n'est pas valide. (jetez un chèque pour cela)

Vous pouvez lancer votre programme F10 ou F11..ou une autre clé en fonction de votre IDE

Quelques conseils

0
Seifo84