通过阅读制表符分隔的文件,并放话说在一个ArrayList

问题描述 投票:10回答:5

我做一个自我学习锻炼,帮助我了解更多关于Java,但我被困在了这个问题。我有以下的txt文件:

Name  Hobby 
Susy  eat fish 
Anna  gardening
Billy bowling with friends

注:名字和爱好是由制表符分隔

什么是阅读所有的线,并把它的ArrayList中(姓名,爱好)的最佳方式。最棘手的部分是,

eat fish or bowling with friends

中有空格,它必须在一个阵列下把,显然我不能硬编码。这里是我当前的代码:

 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

我怀疑计数的指标是不是一个选项卡上是非常有用的。任何想法?

java file-io tabs
5个回答
9
投票

好吧,你需要做如下所示的配方:

  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

3
投票

如果您有标签\t分离名称和业余爱好列,你应该做这样的事情(不要忘记在年底前关闭扫描):

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
投票

对于其他人仍然磕磕绊绊已在此。

使用Stream API(Java 8),这是可以做到的

由此可见

  • 过滤方法的第一报头元件从列表中过滤
  • 地图的方法来在流中的每个元素映射到新的流的另一元件。
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} 

0
投票

因为当你分析出选项卡上有一个分隔符今后引用,如“\ t”的标签对。用这个来代替.split(”“)

此外,当被抛出你的错误,因为这意味着未找到任何字符,因此-1,所以当你试图将其存储在一个数组... -1是无效的。 (在该支票扔)

你可以一步一步把你的程序F10或F11..or其他一些关键取决于你的IDE

只是一些小技巧


0
投票

你应该尝试的commons-lang library。在许多其他有用的东西,你可以使用一个分隔符分割字符串:

String x="Billy bowling with friends";

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

假设有Billybowling之间的选项卡,

  • Y [0]包含 “比利”
  • y1包含“与朋友一起打保龄球”
© www.soinside.com 2019 - 2024. All rights reserved.