Добавление токенов из файла .csv в ArrayList в Java - PullRequest
0 голосов
/ 20 февраля 2012

У меня возникли проблемы при создании ArrayList в Java из токенов, которые я получаю из файла .csv. Я пытался понять это часами, но безуспешно. Без создания ArrayList все мои токены распечатываются без проблем, но когда я создаю ArrayList, чтобы добавить их, у меня возникают проблемы. Для файла .csv, состоящего из 60+ строк и 9 токенов (строк) для каждой строки, я распечатываю то, что имею, перед добавлением в 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 имеет тип 'string', но мне нужно использовать <String> для ввода моих токенов в ArrayList, состоящий из <Strings>, но не знаю, как это сделать. Любая помощь / советы / отзывы очень ценятся !!!

Ответы [ 5 ]

2 голосов
/ 20 февраля 2012

A) Вы звоните st.nextToken() дважды каждый раз, когда делаете цикл. Вы просто потеряли все остальные токены, и в конце концов он рвется, потому что при втором вызове ... его нет (если у вас было 10 элементов на строку в вашем CSV-файле, это было бы успешно, и у вас было бы 5 вещей в вашем ArrayList)

B) Не используйте StringTokenizer в новом коде. Javadoc объясняет, что это унаследованный класс, и вместо него следует использовать String.split().

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

Готово.

Отредактируйте, чтобы добавить: если вам действительно нужен ArrayList, а не массив, вы можете сделать:

ArrayList<String> list = new ArrayList<String>(Arrays.asList(elements));
0 голосов
/ 20 февраля 2012

Как уже упоминалось в других ответах, ваша проблема заключается в вызове 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]);
}
0 голосов
/ 20 февраля 2012

метод nextToken вызывается дважды в цикле, вам может потребоваться изменить код на что-то вроде:

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

                            list.add(tempStr);
                    }
0 голосов
/ 20 февраля 2012

вы прыгаете на два элемента вперед каждый раз, когда делаете цикл. Код прочитайте токен и затем используйте его:

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

А потом:

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

                            list.add(token);
0 голосов
/ 20 февраля 2012

Вы уже делаете st.nextToken в вашем System.out. Так что токен больше не будет существовать. Если вам это нужно в System.out, сначала присвойте st.nextToken переменной, а затем используйте ее.

...