11

Java について理解を深めるために自己学習演習を行っていますが、この質問に行き詰まっています。次のtxtファイルがあります。

Name  Hobby 
Susy  eat fish 
Anna  gardening
Billy bowling with friends

名前と趣味はタブ区切り

すべての行を読み取り、それを arraylist(name,hobby) に入れる最良の方法は何ですか。トリッキーな部分は、

eat fish or bowling with friends

には空白があり、1 つの配列の下に配置する必要があり、明らかにハードコードすることはできません。これが私の現在のコードです:

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

エラーが発生しました:

java.lang.StringIndexOutOfBoundsException: 文字列インデックスが範囲外です: -1

タブでインデックスを数えることはあまり役に立たないと思います。何か案が?

4

5 に答える 5

12

さて、以下に示すレシピを実行する必要があります。

  1. 作成するBufferedReader
  2. を作成するArrayList<String>
  3. Stringという名前の変数へのデータの読み取りを開始しますlineJustFetched
  4. Stringを呼び出して分割するlineJustFetched.split("\t");
  5. 生成されたものを反復しString[]ます。に入力したいトークンArrayList""
  6. そうでない場合は、その単語をArrayList

\t空白が問題にならないように、値 に基づいて分割する必要があることを指定します。

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

出力

John
likes to play tennis
Sherlock
likes to solve crime
于 2013-10-24T19:58:34.887 に答える
1

まだこれに出くわしている他の人のために。

API (Java 8)を使用Streamすると、これは次のように実行できます。

これは

  • リストから最初のヘッダー要素をフィルタリングするための Filter メソッド
  • ストリーム内の各要素を新しいストリームの別の要素にマップする map メソッド。
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();
    }
  }
}

そして出力

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

==HashMap==
{Susy=eat fish}
{Anna=gardening}
{Billy=bowling with friends} 
于 2016-11-08T22:09:29.733 に答える
0

commons-lang ライブラリを試す必要があります。デリミタを使用して文字列を分割できる便利な機能は他にもたくさんあります。

String x="Billy bowling with friends";

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

と の間にタブがあると仮定するBillybowling

  • y[0] には「ビリー」が含まれています
  • y 1には「友達とボウリング」が含まれています
于 2013-10-24T20:11:09.620 に答える
0

タブを解析するときの将来の参照のために、タブの「\ t」などの区切り文字があります。.split(" ") の代わりにそれを使用してください

また、文字が見つからないことを意味するためにエラーがスローされた場合、したがって -1 であるため、配列に格納しようとすると... -1 は無効です。(そのための小切手を投げます)

IDEに応じて、プログラムのF10またはF11..またはその他のキーをステップスローできます

いくつかのヒント

于 2013-10-24T20:15:08.483 に答える