奇数ArrayList索引超出范围异常

时间:2016-01-26 22:04:10

标签: java algorithm for-loop

我正在尝试创建一个程序,该程序将获取给定单词并找到可以由给定单词内的字母组成的单词列表。这是我的代码:

package wordfinder;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;

public class WordFinder {
    public static void main(String[] args) throws IOException {
        List<String> wordList1 = Files.readAllLines(Paths.get("res", "WordList1.txt"));
        List<String> wordList2 = Files.readAllLines(Paths.get("res", "WordList2.txt"));

        Scanner scan = new Scanner(System.in);

        System.out.println("Please enter the string you would like this program to find words in.");
        String wordToFind = scan.nextLine();

        ArrayList<String> words = new ArrayList<>();
        ArrayList<Character> charArray = new ArrayList<>();
        char[] charList = wordToFind.trim().toCharArray();

        for (int i = 0; i < charList.length; i++) {
            charArray.add(charList[i]);
        }

        for (int i = 0; i < wordList1.size(); i++) {
            char[] charsInWordToCheckAgainst = wordList1.get(i).toCharArray();
            ArrayList<Boolean> containsLetter = new ArrayList<>(charsInWordToCheckAgainst.length);

            for (int j = 0; j < charsInWordToCheckAgainst.length; j++) {
                if (charArray.contains(charsInWordToCheckAgainst[j])) {
                    containsLetter.set(j, true);
                }
            }

            if (areAllTrue(containsLetter)) {
                words.add(wordList1.get(i));
            }
        }

        for (int i = 0; i < wordList2.size(); i++) {
            for (int j = 0; j < wordList2.get(i).length(); j++) {
                char[] charsInWordToCheckAgainst = wordList2.get(i).toCharArray();
                ArrayList<Boolean> containsLetter = new ArrayList(charsInWordToCheckAgainst.length);

                for (int k = 0; k < charsInWordToCheckAgainst.length; k++) {
                    if (charArray.contains(charsInWordToCheckAgainst[k])) {
                        containsLetter.set(k, true);
                    }
                }

                if (areAllTrue(containsLetter)) {
                    words.add(wordList2.get(i));
                }
            }
        }

        System.out.println("Words found: " + words.size());

        for(int i = 0; i < words.size(); i++) {
            System.out.println("Word " + i + ": " + words.get(i));

            try {
                TimeUnit.MILLISECONDS.sleep(1);
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
        }
    }

    public static boolean areAllTrue(ArrayList<Boolean> bools) {
        for (int i = 0; i < bools.size(); i++) {
            if (!bools.get(i)) {
                return false;
            }
        }

        return true;
    }
}

这是我得到的错误:

Please enter the string you would like this program to find words in.
abcdefghijklmnopqrstuvwxyz
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 0
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.set(ArrayList.java:444)
    at wordfinder.WordFinder.main(WordFinder.java:36)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

Process finished with exit code 1

为了澄清,WordFinder.java:36在wordList1 for循环中是containsLetter.set(j, true);。所以我真的不明白为什么数组的大小为0. containLetter不应该是0。

更新1

将wordList1更新为循环:

for (int i = 0; i < wordList2.size(); i++) {
    for (int j = 0; j < wordList2.get(i).length(); j++) {
        char[] charsInWordToCheckAgainst = wordList2.get(i).toCharArray()
        ArrayList<Boolean> containsLetter = new ArrayList<>();
        Collections.fill((List) containsLetter, charsInWordToCheckAgainst.length);

        for (int k = 0; k < charsInWordToCheckAgainst.length; k++) {
            if (charArray.contains(charsInWordToCheckAgainst[k])) {
                containsLetter.set(k, true);
            }
        }

        if (areAllTrue(containsLetter)) {
            words.add(wordList2.get(i));
        }
    }
}

但这仍然给我同样的错误。

1 个答案:

答案 0 :(得分:1)

根据javadoc对于ArrayList构造函数new ArrayList<>(charsInWordToCheckAgainst.length),接受单个参数 - 这是列表的初始容量。容量 - 而不是大小。

差异如下。 大小 - 是列表中存储的元素数。 容量 - 是为此结构创建的初始数组大小。

E.g。无论何时将元素添加到列表,它都会检查 - 我是否有容量,如果没有 - 重新分配新数组。将此参数提供给构造函数的目的是减少重新分配的数量。为了预填充列表 - 您需要手动放置元素或使用第3方库提供的实用程序功能。