2013-10-24 9 views
9

Ich mache eine selbstlernende Übung, um mir zu helfen, mehr über Java zu verstehen, aber ich bin bei dieser Frage fest. Ich habe folgende txt-Datei:Lesen Sie eine Datei getrennt durch Tab und setzen Sie die Wörter in eine ArrayList

Name Hobby 
Susy eat fish 
Anna gardening 
Billy bowling with friends 

Hinweis: Name und Hobby durch Reiter getrennt sind

Was ist der beste Weg, um die ganze Zeile zu lesen und es in Arraylist setzen (Name, Hobby). Der schwierige Teil ist, dass

eat fish or bowling with friends 

weiße Flächen hat, und es muss unter einem Array gesetzt werden und natürlich kann ich es nicht hart codieren. Hier ist mein aktueller Code:

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

Ich habe einen Fehler:

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

Ich vermute, das Zählen den Index ist nicht sehr nützlich, auf einer Registerkarte. Irgendeine Idee?

+0

Stellen Sie sicher keine neue/leere Zeile am Ende der Datei vorhanden ist. – srkavin

Antwort

7

In Ordnung, müssen Sie das Rezept unten tun:

  1. ein BufferedReader erstellen
  2. eine ArrayList<String>
  3. Anfang Lesen von Daten in eine String Variable lineJustFetched Namen erstellen.
  4. die Split String von lineJustFetched.split("\t");
  5. Iterate über die String[] produziert aufrufen. Überprüfen Sie, ob das Token Sie in die ArrayList eingeben möchten nicht ""
  6. ist Falls nicht, fügen Sie das Wort zum ArrayList

Sie angeben, dass Sie basierend auf \t Werte zu teilen brauchen so White Spaces nicht ein Problem.

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

Ausgabe

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

hi ive Bearbeiten Sie meinen Quellcode wie Sie es angewiesen haben .. ist es korrekt? – user2891092

+0

@ user2891092 Ich habe eine SSCCE für Sie veröffentlicht. –

+0

aber es alles in eine Arraylist. ist es möglich, sie in zwei arraylist zu trennen (ex. John ist in Namen und spielt gern Tennis ist Hobby) gesetzt? – user2891092

0

Sie sollten die commons-lang-Bibliothek versuchen. http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/index.html Unter viele andere nützliche Dinge können Sie eine Zeichenfolge mit einem Trennzeichen aufgeteilt:

String x="Billy bowling with friends";

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

Unter der Annahme, als Reiter zwischen Billy und Bowling ist, y [0] enthält "Billy" y [1] enthält " bowling with friends "

0

Für zukünftige Referenzen, wenn Sie Tab ausparse gibt es ein Trennzeichen wie" \ t "für Registerkarte. Verwenden Sie das anstelle von.split ("")

Auch wenn Ihr Fehler ausgelöst wird, weil es bedeutet, dass kein Zeichen gefunden wird, daher die -1, wenn Sie also versuchen, es in einem Array zu speichern ... -1 ist nicht gültig. (Wirft einen Scheck für die)

Sie treten Ihr Programm F10 werfen können oder eine andere Taste F11..or auf Ihrem IDE je

Nur einige Tipps

2

Wenn Sie Namen und Hobby getrennt Spalt mit \t Registerkarte, sollten Sie etwas tun (und nicht vergessen Scan am Ende zu schließen):

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

Für andere noch auf dem stolpern.

Verwendung Stream API (Java 8), kann dies geschehen, wie

Dies zeigt

  • Filter Methode das erste Kopfelement aus der Liste
  • Karte Verfahren zum Filtern jedes Element zur Karte in Stream zu einem anderen Element für neuen 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(); 
    } 
    } 
} 

Und die Ausgabe

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

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