【问题标题】:Adding tokens from .csv file to ArrayList in Java在 Java 中将令牌从 .csv 文件添加到 ArrayList
【发布时间】:2012-02-20 05:26:07
【问题描述】:

我在 Java 中使用从 .csv 文件获得的令牌创建 ArrayList 时遇到了问题。我一直试图弄清楚几个小时,但没有成功。如果不创建ArrayList,我的所有令牌都可以毫无问题地打印出来,但是当我创建一个ArrayList 来添加它们时,我遇到了麻烦。对于由 60 多行和每行 9 个标记(字符串)组成的 .csv 文件,我在添加到 ArrayList 之前打印出我拥有的内容,但是在创建 ArrayList 并向它们添加标记之后,我只能打印出在我遇到NoSuchElementException 之前的前几个令牌。

这是我所有的代码:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.StringTokenizer; 
import java.lang.String;
import java.util.ArrayList; 
import java.util.*; //probably redundant
import java.util.Scanner;  

public class TTcompiler18Feb {

   private static ArrayList<String> list;

   public static void main(String[] args) {

    try
    {
      //csv file containing data
      String strFile = "FileWithTokens.csv";

      //create BufferedReader to read csv file
      BufferedReader br = new BufferedReader( new FileReader(strFile));

      String strLine = "";
      StringTokenizer st = null;
      int lineNumber = 0, tokenNumber = 0;

      list = new ArrayList<String>();
      String token;

      //read comma separated file line by line
      while( (strLine = br.readLine()) != null)
      {
        lineNumber++; 
        st = new StringTokenizer(strLine, ",");

        while(st.hasMoreTokens())
        {
          tokenNumber++;       
          System.out.println("Line # " + 
                             lineNumber + ", Token # " + 
                             tokenNumber + ", Token : "+ 
                             st.nextToken()); 
          list.add(st.nextToken());
        }
        //reset token number
        tokenNumber = 0;
      }
      System.out.println("The size of your list is: " + list.size());
    }
    catch(Exception e)
    {
      System.out.println("Exception while reading csv file: " + e);                  
    }
  }
}

我运行我的代码并得到以下信息:

运行 TTcompiler18Feb

Line # 1, Token # 1, Token : Row1Token1
Line # 1, Token # 2, Token : Row1Token2
Line # 1, Token # 3, Token : Row1Token3
Line # 1, Token # 4, Token : Row1Token4
Line # 1, Token # 5, Token : Row1Token5
Exception while reading csv file: java.util.NoSuchElementException

除了list.add(st.nextToken());,我还尝试以其他方式添加到我的列表中,例如使用.toString 方法、类型转换st.nextToken(),以及将变量分配给st.nextToken(),如下所示:

token = st.nextToken().toString();  //defined as string type outside loop
list.add(token);

...但这些方法似乎都不起作用。

该程序的目标是获取传入 .csv 文件中的所有令牌,并将它们整齐地放入 ArrayList 以供以后使用。我对 Java 还是很陌生,并且仍然不清楚泛型如何在解决这个问题中发挥作用。据我了解,StringTokenizer 属于“字符串”类型,但我需要使用&lt;String&gt; 将我的令牌输入到由&lt;Strings&gt; 组成的ArrayList 中,但不知道该怎么做。非常感谢任何帮助/提示/反馈!!!

【问题讨论】:

    标签: java generics arraylist stringtokenizer token


    【解决方案1】:

    A) 每次循环时,您都会调用 st.nextToken() 两次。您只是丢失了所有其他令牌,最终它吐了,因为在第二次调用时......没有一个(如果您的 csv 文件中每行有 10 个项目,它会成功并且您的 @ 中有 5 个项目987654322@)

    B) 不要在新代码中使用StringTokenizer。它的 Javadoc 解释说它是一个遗留类,并改为使用 String.split()

    String[] elements = strLine.split(",");
    

    完成。

    编辑添加:如果您真的需要ArrayList 而不是数组,那么您可以这样做:

    ArrayList<String> list = new ArrayList<String>(Arrays.asList(elements));
    

    【讨论】:

      【解决方案2】:

      每次循环时,您都会向前跳跃两个元素。代码读取令牌然后使用它:

      String token = ""; 
      token = st.nextToken();
      

      然后:

                                  System.out.println("Line # " + 
                                                     lineNumber + ", Token # " + 
                                                     tokenNumber + ", Token : "+ 
                                                     token ); 
      
                                  list.add(token);
      

      【讨论】:

        【解决方案3】:

        nextToken 方法在循环中被调用了两次,您可能需要将代码更改为:

        while(st.hasMoreTokens())
                            {
                                    tokenNumber++;       
                                    String tempStr = st.nextToken();
                                    System.out.println("Line # " + 
                                                       lineNumber + ", Token # " + 
                                                       tokenNumber + ", Token : "+ 
                                                       tempStr); 
        
                                    list.add(tempStr);
                            }
        

        【讨论】:

        • 我不敢相信我错过了。谢谢大家!
        【解决方案4】:

        正如其他答案中提到的,您的问题是在一次迭代中多次调用 nextToken,这不是它的预期使用方式。

        与其使用笨拙的旧StringTokenizer,不如使用String.split()

        String[] tokens = strLine.split(",");
        
        for(int i = 0; i < tokens.length; i++) { 
            System.out.println("Line # " + 
                                lineNumber + ", Token # " + 
                                i+ ", Token : "+ 
                                token[i]);       
            // do you even need a list?
            list.add(token[i]);
        }
        

        【讨论】:

          【解决方案5】:

          您已经在您的System.out 中执行st.nextToken。所以令牌将不再存在。如果您在System.out 中需要它,请先将st.nextToken 分配给一个变量,然后再使用它。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2022-01-09
            • 1970-01-01
            • 1970-01-01
            • 2013-05-19
            • 1970-01-01
            • 1970-01-01
            • 2013-07-02
            相关资源
            最近更新 更多