我看不出我的代码有什么问题: -
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
int[] A = new int[] {2, 1, 1, 2, 3, 1};
ArrayList<Integer> foundNumbers = new ArrayList<>();
int distinct = 0;
for(int i = 0; i < A.length-1; i++) {
if(foundNumbers.get(i-1) == null) {
foundNumbers.set((i-1), A[i]);
distinct++;
}
}
System.out.println(distinct);
}
}
我想检查Array element i的值是否已经分配给ArrayList元素i-1,然后递增distinct变量并打印数组中有多少个不同的值。
当我将i的值更改为1时,这是例外: -
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:604)
at java.util.ArrayList.get(ArrayList.java:382)
at tdd.Main.main(Main.java:19)
答案 0 :(得分:2)
列表完全为空。你没有在其中添加任何内容,但是你正试图通过foundNumbers.get
调用从中读取元素,因此任何索引都将超出范围。
要将A
中的唯一元素添加到列表中,get
和set
只是要调用的错误列表方法,请使用contains
和add
这就是你想要做的事情:
for (int x : A) {
if (!foundNumbers.contains(x))
foundNumbers.add(x);
}
以上是与上述相同的逻辑,以更详细的方式编写,可能更容易理解所涉及的内容:
for (int i = 0; i < A.length; i++) {
boolean found = false;
for (int j = 0; j < foundNumbers.size(); j++) {
if (A[i] == foundNumbers.get(j)) {
found = true;
break;
}
}
if (!found) {
foundNumbers.add(A[i]);
}
}
您不需要单独的distinct
变量,因为它只是foundNumbers.size()
。
虽然这有效,但如果元素的数量很大,List
对于消除重复项效率不高,因为每个contains
调用都需要通过列表内容的另一个循环。 Set
自动防止重复并在内部构建其内容,使其有效地执行此操作:
Set<Integer> distinct = new TreeSet<>();
for (int x : A) distinct.add(x);
System.out.println(distinct); // [1, 2, 3]
答案 1 :(得分:1)
for(int i = 0; i < A.length-1; i++) {
if(foundNumbers.get(i-1) == null) {
在该循环的第一次迭代中,i
将设置为零,因此第二行正在执行.get(-1)
。
答案 2 :(得分:1)
有很多问题:
你的循环应该是:
for (int i = 0; i < A.length - 1; i++) {
if (foundNumbers.size() > i && foundNumbers.get(i) == null) {//or better you use contains method of list like foundNumbers.contains(someNumber);
foundNumbers.add(A[i]);
distinct++;
}
}