Java 读取由制表符分隔的文件并将单词放入 ArrayList

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19575308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 18:27:24  来源:igfitidea点击:

Read a file separated by tab and put the words in an ArrayList

javafile-iotabs

提问by user2891092

I am doing a self learning exercise to help me understand more about Java, but I am stuck at this question. I have the following txt file:

我正在做一个自学练习,以帮助我更多地了解 Java,但我被困在这个问题上。我有以下txt文件:

Name  Hobby 
Susy  eat fish 
Anna  gardening
Billy bowling with friends

Note: name and hobby are separated by tab

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

What is the best way to read all the line and put it in arraylist(name,hobby). The tricky part is that

阅读所有行并将其放入 arraylist(name,hobby) 的最佳方法是什么。棘手的部分是

eat fish or bowling with friends

has white spaces and it must be put under one array and obviously I cannot hardcode it. Here is my current 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");

I got an error:

我有一个错误:

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

java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:-1

I suspect counting the index is not very useful on a tab. Any idea?

我怀疑在选项卡上计算索引不是很有用。任何的想法?

采纳答案by Little Child

Alright, you need to do the recipe shown below:

好的,您需要执行如下所示的食谱:

  1. Create a BufferedReader
  2. Create an ArrayList<String>
  3. Start reading data into a Stringvariable named lineJustFetched.
  4. Split the Stringby calling lineJustFetched.split("\t");
  5. Iterate over the String[]produced. Check if the token you want to enter into the ArrayListis not ""
  6. If not, add the word to the ArrayList
  1. 创建一个 BufferedReader
  2. 创建一个 ArrayList<String>
  3. 开始将数据读入String名为的变量lineJustFetched
  4. String通过调用拆分lineJustFetched.split("\t");
  5. 迭代String[]产生的。检查您要输入的令牌是否ArrayList不是""
  6. 如果没有,请将该词添加到 ArrayList

You specify that you need to split based on \tvalues so white spaces won't be an issue.

您指定需要根据\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();
        }
    }
}    

Output

输出

John
likes to play tennis
Sherlock
likes to solve crime

回答by windjammer

You should try the commons-lang library. Among many other useful things you can split a string using a delimiter:

您应该尝试使用commons-lang 库。在许多其他有用的东西中,您可以使用分隔符拆分字符串:

String x="Billy bowling with friends";

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

Assuming there is a tab between Billyand bowling,

假设Billy和之间有一个制表符bowling

  • y[0] contains "Billy"
  • y1contains "bowling with friends"
  • y[0] 包含“比利”
  • y 1包含“与朋友打保龄球”

回答by Seifo84

For future references when you parse out tab there is a delimiter such as "\t" for tab. Use that instead of .split(" ")

对于将来解析制表符时的参考,制表符有一个分隔符,例如“\t”。使用它而不是 .split(" ")

Also, when your error is thrown because it means no character is found, hence the -1, so when you try to store it in an Array... -1 is not valid. (throw in a check for that)

此外,当您的错误被抛出时,因为这意味着找不到字符,因此是 -1,因此当您尝试将其存储在数组中时...-1 无效。(为此投入一张支票)

You can step throw your program F10 or F11..or some other key depending on your IDE

您可以根据您的 IDE 逐步抛出程序 F10 或 F11 .. 或其他一些键

Just some tips

只是一些提示

回答by Arya

If you separated Name and Hobby column with tab \t, you should do something like this (and don't forget to close scan at end):

如果你用 tab 分隔 Name 和 Hobby 列\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();
}

回答by bhavya.work

For others still stumbling upon this.

对于其他人仍然绊倒这一点。

Using StreamAPI (Java 8), this can be done as

使用StreamAPI (Java 8),这可以作为

This shows

由此可见

  • Filter method to filter the first header element from the list
  • map method to map each element in stream to another element for new stream.
  • 过滤方法从列表中过滤第一个标题元素
  • 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();
    }
  }
}

And the output

和输出

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

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