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
冗余。当东西不起作用时