2013-10-24 9 views
9

Sto facendo un esercizio di autoapprendimento per aiutarmi a capire di più su Java, ma sono bloccato a questa domanda. Ho il seguente file txt:Leggere un file separato da tab e mettere le parole in un ArrayList

Name Hobby 
Susy eat fish 
Anna gardening 
Billy bowling with friends 

Nota: nome e hobby sono separati da scheda

Qual è il modo migliore per leggere tutta la linea e metterlo in ArrayList (nome, hobby). La parte difficile è che

eat fish or bowling with friends 

ha spazi bianchi e deve essere messo sotto un array e ovviamente non può hardcode esso. Qui è il mio codice corrente:

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

ho ottenuto un errore:

java.lang.StringIndexOutOfBoundsException: String index out of range: -1

Ho il sospetto contando l'indice non è molto utile su una scheda. Qualche idea?

+0

Assicurarsi che nessuno nuova linea/vuota è presente alla fine del file. – srkavin

risposta

7

Va bene, è necessario fare la ricetta riportata di seguito:

  1. Creare un BufferedReader
  2. Creare un inizio la lettura dei dati ArrayList<String>
  3. in una variabile denominata StringlineJustFetched.
  4. Spalato il String chiamando lineJustFetched.split("\t");
  5. iterare il String[] prodotta. Controllare se il token si vuole entrare nella ArrayList non è ""
  6. caso contrario, aggiungere la parola al ArrayList

Si specifica che è necessario dividere in base a valori \t così spazi bianchi non saranno un problema.

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

uscita

John 
likes to play tennis 
Sherlock 
likes to solve crime 
+0

hi ive modifica il mio codice sorgente come da istruzioni .. è corretto? – user2891092

+0

@ user2891092 Ho pubblicato un SSCCE per te. –

+0

ma mette tutto in un unico arraylist. è possibile separarli in due arraylist (ad esempio john è messo nei nomi e gli piace giocare a tennis è un hobby)? – user2891092

0

Si dovrebbe cercare la libreria commons-lang. http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/index.html Tra le molte altre cose utili si possono dividere una stringa utilizzando un delimitatore:

String x="Billy bowling with friends";

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

presumere che vi sia come scheda tra Billy e bowling, y [0] contiene "Billy" y [1] contiene " bowling con gli amici "

0

Per i riferimenti futuri quando si analizza la scheda è presente un delimitatore come" \ t "per scheda. Usa quello al posto di.split ("")

Inoltre, quando viene generato l'errore perché significa che nessun carattere viene trovato, da cui il -1, quindi quando si tenta di memorizzarlo in un array ... -1 non è valido. (Gettare in un assegno di che)

è possibile passaggio gettare il vostro programma o F10 F11..or qualche altro tasto a seconda del vostro IDE

solo alcuni suggerimenti

2

Se separati Nome e Hobby colonna con scheda \t, si dovrebbe fare una cosa del genere (e non dimenticare di chiudere la scansione alla fine):

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

per altri ancora inciampare su questo.

Uso Stream API (Java 8), questo può essere fatto come

Questo dimostra

  • metodo Filtro per filtrare il primo elemento di intestazione dall'elenco
  • metodo map per mappare ciascun elemento passare a un altro elemento per il nuovo stream.
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(); 
    } 
    } 
} 

E l'uscita

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

==HashMap== 
{Susy=eat fish} 
{Anna=gardening} 
{Billy=bowling with friends}