Java 无法找到基于数组的deque的问题,但正在获取边界外异常
一段时间以来,我一直在试图弄明白这一点,但没有结果。我想我的代码肯定有几个我看不见的问题。我以前用过一种稍微复杂一点的方式来实现它,并用一种更简单的形式来写它,以帮助一位在我下面挣扎的朋友,但我只是把自己弄得一团糟 代码如下:Java 无法找到基于数组的deque的问题,但正在获取边界外异常,java,deque,Java,Deque,一段时间以来,我一直在试图弄明白这一点,但没有结果。我想我的代码肯定有几个我看不见的问题。我以前用过一种稍微复杂一点的方式来实现它,并用一种更简单的形式来写它,以帮助一位在我下面挣扎的朋友,但我只是把自己弄得一团糟 代码如下: public class ArrayBasedDeque<EltType> implements Deque<EltType> { private final int CAPACITY = 10; private int capacit
public class ArrayBasedDeque<EltType> implements Deque<EltType> {
private final int CAPACITY = 10;
private int capacity;
private int end;
private EltType deque[];
public ArrayBasedDeque() {
this.capacity = CAPACITY;
deque = (EltType[]) (new Object[capacity]);
}
public EltType first() {
return deque[0];
}
public EltType last() {
return deque[end];
}
public boolean isEmpty() {
return end == 0;
}
public int size() {
return deque.length;
}
public boolean isFull() {
int curSize = size();
return curSize >= capacity;
}
public void insertFirst(EltType first) {
if(!isEmpty()) {
EltType[] tempArray;
tempArray = (EltType[]) new Object[capacity+1];
for (int i=0;i<deque.length;i++) {
tempArray[i+1] = deque[i];
}
deque = tempArray;
}
deque[0] = first;
end++;
}
public void insertLast(EltType last) {
if (isFull()){
EltType[] tempArray;
tempArray = (EltType[]) new Object[CAPACITY+1];
for (int i=0;i<deque.length;i++) {
tempArray[i] = deque[i];
}
}
deque[end] = last;
end++;
}
public EltType removeFirst() {
EltType[] tempArray;
EltType returned = deque[0];
tempArray = (EltType[]) new Object[capacity];
for (int i=1;i<capacity;i++) {
tempArray[i-1] = deque[i];
}
deque = tempArray;
end--;
return returned;
}
public EltType removeLast() {
EltType[] tempArray;
System.out.println(end);
EltType returned = deque[end];
tempArray = (EltType[]) new Object[capacity];
for (int i=0;i<deque.length;i++) {
tempArray[i] = deque[i];
}
deque = tempArray;
return returned;
}
}
这将返回一个错误
java.lang.ArrayIndexOutOfBoundsException: 11
at ArrayBasedDeque.insertFirst(ArrayBasedDeque.java:37)
at TestABD.main(TestABD.java:7)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:271)
insertLast方法也是如此。我想不出来,希望斯塔克沃夫仔细的凝视能帮助我。非常感谢 我在Java方面没有太多经验,所以我在这里可能不太靠谱,但是……当您首先调用InsertFirst时,还没有将值设置为capacity。因此它默认为0或垃圾。不管怎样,当你打电话的时候 tempArray=(EltType[])新对象[容量+1];
容量将为1或…某个“随机”数。所以我们为什么要离开边界。我猜你想用容量 我在Java方面没有太多经验,所以我在这里可能不太靠谱,但是……当您首先调用InsertFirst时,还没有将值设置为capacity。因此它默认为0或垃圾。不管怎样,当你打电话的时候
tempArray = (EltType[]) new Object[capacity+1];
for (int i=0;i<deque.length;i++) {
tempArray[i+1] = deque[i];
}
deque = tempArray;
tempArray=(EltType[])新对象[容量+1];
容量将为1或…某个“随机”数。所以我们为什么要离开边界。我猜你想用容量
tempArray = (EltType[]) new Object[capacity+1];
for (int i=0;i<deque.length;i++) {
tempArray[i+1] = deque[i];
}
deque = tempArray;
它超过了只有11个插槽([0]
到[10]
)的tempArray
的末尾
简单的解决方法是将for循环从0
转到capacity
,而不是从0
转到deque.length
,但我不确定这是否实现了您想要的实际行为。另一种方法是分配tempArray=newobject[deque.length+1]
,但是capacity
实际上并不意味着capacity,它在概念上可能仍然不能反映您认为在这种情况下的“正确”行为
它超过了只有11个插槽([0]
到[10]
)的tempArray
的末尾
简单的解决方法是将for循环从0
转到capacity
,而不是从0
转到deque.length
,但我不确定这是否实现了您想要的实际行为。另一种方法是分配tempArray=newobject[deque.length+1]
,但是capacity
实际上并不意味着capacity,它可能仍然不能从概念上反映您认为在这种情况下的“正确”行为。下面是对该特定错误的答案。您没有更新实例变量capacity
,因此每次调用insertFirst
时,临时数组实际上并没有增长。因此,代码应该如下所示:
public void insertFirst(EltType first) {
if (!isEmpty()) {
EltType[] tempArray;
capacity += 1;
tempArray = (EltType[]) new Object[capacity];
for (int i = 0; i < deque.length; i++) {
tempArray[i + 1] = deque[i];
}
deque = tempArray;
}
deque[0] = first;
end++;
}
public void insertFirst(类型优先){
如果(!isEmpty()){
elt类型[]临时数组;
容量+=1;
tempArray=(EltType[])新对象[容量];
for(int i=0;i
尽管如此,总的分类还是远远不正确。下面是这个特定错误的答案。您没有更新实例变量capacity
,因此每次调用insertFirst
时,临时数组实际上并没有增长。因此,代码应该如下所示:
public void insertFirst(EltType first) {
if (!isEmpty()) {
EltType[] tempArray;
capacity += 1;
tempArray = (EltType[]) new Object[capacity];
for (int i = 0; i < deque.length; i++) {
tempArray[i + 1] = deque[i];
}
deque = tempArray;
}
deque[0] = first;
end++;
}
public void insertFirst(类型优先){
如果(!isEmpty()){
elt类型[]临时数组;
容量+=1;
tempArray=(EltType[])新对象[容量];
for(int i=0;i
尽管如此,整个类仍然远远不正确。您是否尝试在调试器中单步执行它?此代码中有很多很多逻辑错误。它似乎也是一个硬件分配。这是真的吗?你试过在调试器中单步执行吗?这段代码中有很多很多逻辑错误。它似乎也是一个硬件分配。真的吗?太棒了,非常感谢你的解释。我总是对.length操作符感到困惑!:)@user476033-当deque已满并且调用了insertFirst
时会发生什么?缓冲区是否应始终扩展(在这种情况下,capacity
是当前容量,而不是容量限制),项目是否会被丢弃,或者insertFirst
是否会失败(可能会无提示地失败,不会留下任何更改)?在这种情况下,缓冲区应始终扩展,在这种情况下,项目将被追加到deque的适当位置[0]。但是,这目前不起作用!:(@user476033那么容量
可能与deque.length
是多余的。当东西不能按预期的方式工作时,最好对每个关键案例的每个方法都有一个好的想法,然后在关键案例中使用调试器遍历每个方法(空、部分满、满到容量)和/或通过代码使用println
s来显示/验证每次方法调用前后的图片。非常感谢您的解释。我总是对.length运算符感到困惑!)@user476033-当deque已满并且调用了insertFirst
时,会发生什么情况?缓冲区是否总是扩展(在这种情况下capacity
是当前容量,而不是容量限制),项目是否会被丢弃,或者insertFirst
是否会失败(可能会自动失败,不会留下任何更改)?在这种情况下,缓冲区应始终扩展,本例中的项目将附加到位置[0]的deque上。但是,这当前不起作用!:(@user476033然后容量可能与deque.length
冗余。当东西不起作用时