索引越过arraylist(java)

时间:2013-04-16 20:21:57

标签: java arrays arraylist range

这是一项家庭作业。我正在尝试制作一个程序,在文本文件中搜索特定的单词,然后打印出单词的频率。

public class WordFreq extends Echo{

ArrayList<WordCount>array1=new ArrayList<WordCount>();
String[] words;
int wordsTotal=0;


public WordFreq(String f, String x) throws IOException
{
  super(f);
  words=x.toLowerCase().split(" ");
}

public void processLine(String line){ 
  String[] lines=line.toLowerCase().split(" ");
  wordsTotal=wordsTotal+lines.length;
  for(int j=0; j<lines.length; j++){
    WordCount alpha=new WordCount(lines[j]);
    alpha.incCount();
    array1.add(alpha);}
  for(int x=0; x<array1.size(); x++){
    for(int y=0; y<array1.size(); y++){
      if(array1.get(x).equals(array1.get(y))&&(x!=y)){
        for(int i = 0; i< array1.get(y).getCount(); i++){
          array1.get(x).incCount();
        }
        array1.remove(y);
      }
    }
  }

}

public void reportFrequencies(){
  for(int i = 0; i<array1.size();i++){
    // System.out.println(array1.get(i).getWord()+" "+array1.get(i).getCount());
  }
  int currentWord=0;
  for(int x=0; x<words.length; x++){
    for(int y=0; y<array1.size(); y++){
      if(words[x].equals(array1.get(y).getWord())){
        currentWord=array1.get(y).getCount();}}
    System.out.print(words[x]+" ");
    System.out.printf("%.4f",(double)currentWord/wordsTotal);
  }
}

}

这是我的主要方法:

public class FreqStudy{
  public static void main(String[] args) throws IOException
  {
    Scanner scan = new Scanner(System.in);
    System.out.println("enter file name");
    String fileName = scan.next();
    Scanner scan2 = new Scanner(System.in);
    System.out.println("enter words to search for");
    System.out.println("enter lower case, separated by spaces");
    String wordString = scan2.nextLine();
    WordFreq f = new WordFreq(fileName,wordString);
    f.readLines();
    f.reportFrequencies();
  }
}

我正在使用Jane Austen所着的Emma一书的.txt文件。这是我运行程序并尝试搜索单词时收到的错误消息:

java.lang.IndexOutOfBoundsException: Index: 906, Size: 906
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at WordFreq.processLine(WordFreq.java:26)
at Echo.readLines(Echo.java:16)
at FreqStudy.main(FreqStudy.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)"

以下是Echo和WordCount的代码:

public class WordCount{

private String word;
private int count;

public WordCount(String w){
word = w;
count = 0;
}

public String getWord(){
return word;}

public int getCount(){
return count;}

public void incCount(){count++;}

public String toString() {
return(word +  " --- " + count);
}

public boolean equals(Object other){
WordCount i = (WordCount)other;
return (this.word.equals(i.word));
}
}

回声:

import java.util.Scanner;
import java.io.*;


public class Echo{
String fileName; // external file name
Scanner scan; // Scanner object for reading from external file

public Echo(String f) throws IOException
{
fileName = f;
scan = new Scanner(new FileReader(fileName));
}

public void readLines(){ // reads lines, hands each to processLine
while(scan.hasNext()){
  processLine(scan.nextLine());
}
scan.close();
}

public void processLine(String line){ // does the real processing work
System.out.println(line);
}
}

我的代码第26行是:

for(int i = 0; i< array1.get(y).getCount(); i++)

3 个答案:

答案 0 :(得分:0)

在嵌套的for循环中,您在操作array1的同时循环大小array1。在迭代时不要改变你用来迭代的任何东西。您可以考虑复制array1进行迭代。

for(int x=0; x<array1.size(); x++){
    for(int y=0; y<array1.size(); y++){
        if(array1.get(x).equals(array1.get(y))&&(x!=y)){
            for(int i = 0; i< array1.get(y).getCount(); i++){
                 array1.get(x).incCount();
            }
            array1.remove(y); // NO NO NO
        }
    }
}

答案 1 :(得分:0)

我认为您的问题是,您在for循环中使用array1.size()作为边界,而您正在从array1中移除值。所以你的y计数器正在递增,你的边界总是在减少。在循环中的特定点,此递增/递减将导致Y将变得大于array1.size的情况,因此当您尝试执行get(y)时,您将超出界限。

尝试类似

的内容
int size = array1.size();  //outside the for loops
....
for(int y=0; y<size; y++){

答案 2 :(得分:0)

如果您想要更改正在迭代的对象,我建议使用Iterator

您可以通过以下操作获取ArrayList上的迭代器:

Iterator<WordCount> iterator = array1.iterator();

这可能会解决您的问题并简化您的代码。请务必使用:

iterator.remove()代替array1.remove(index)