Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用数组实现的缓存-ArrayIndexOutOfBoundsException(Java)_Java_Arrays_Caching_Indexoutofboundsexception - Fatal编程技术网

使用数组实现的缓存-ArrayIndexOutOfBoundsException(Java)

使用数组实现的缓存-ArrayIndexOutOfBoundsException(Java),java,arrays,caching,indexoutofboundsexception,Java,Arrays,Caching,Indexoutofboundsexception,我模拟了一个web缓存替换算法。我有N个Request类型的对象可用于缓存,L个对象请求以串行方式到达缓存 请求对象通过其int字段reqID(从0到N-1的数字ID)进行区分。我有覆盖等于能够比较请求对象 我使用一个数组实现一个缓存——一个简单、简单、静态的数组 缓存中填充了Request类型的对象,最大大小为M: /** Max cache size */ private int M; /** Cache */ private Request[] cache = new Request[M

我模拟了一个web缓存替换算法。我有N个Request类型的对象可用于缓存,L个对象请求以串行方式到达缓存

请求对象通过其int字段reqID(从0到N-1的数字ID)进行区分。我有覆盖等于能够比较请求对象

我使用一个数组实现一个缓存——一个简单、简单、静态的数组

缓存中填充了Request类型的对象,最大大小为M:

/** Max cache size */
private int M;

/** Cache */
private Request[] cache = new Request[M];
我在缓存中插入、逐出和替换对象

我还有一个滑动窗口,显示作为ArrayQue实现的最后K个请求:

/** Max window size */
private int K;

/** Window */
private Deque<Request> window = new ArrayDeque<Request>(K);
原因是,因为我的缓存是一个普通数组而不是ArrayList,所以它没有size()方法,而length字段是给定的固定容量,而不是当前缓存大小。因此,为了获得当前缓存大小,我应该执行以下操作(请看一看,因为我不是100%,如果正确的话):

我几乎在该方法的开头,即第1个if块的第1行得到了信息:

// insert item at index counter
this.cache[counter] = request;
。。。我真的不知道为什么

编辑:这是我的构造函数:

/**
 * Constructor
 * @param M Max cache size
 * @param K Max window size
 * @param N Number of items
*/
public Algorithm(int M, int K, int N) {

    // initialize max cache size and max window size
this.M = M;
this.K = K;

// initialize counter
counter = 0;

// initialize isMoreThanOne flag
isMoreThanOne = false;

// allocate inCache, winFreqs, and positions maps
inCache     = new HashMap<Integer, Boolean>(N);
scores          = new HashMap<Integer, Integer>(N);
positions   = new HashMap<Integer, Integer>(N);

}

private int M = 0;
所以如果你不给它赋值

    // set counter
    counter = M-1; //if M == 0, then counter = -1

    // insert item at index counter
    this.cache[counter] = request;    // if counter == -1, then you'll get an exception here
我会把信息还给你

java.lang.ArrayIndexOutOfBoundsException: -1
注意

private Request[] cache = new Request[M];
其中M==0仍然是一个有效的Java数组初始化,但不能向其中添加任何内容

private int M = 0;
所以如果你不给它赋值

    // set counter
    counter = M-1; //if M == 0, then counter = -1

    // insert item at index counter
    this.cache[counter] = request;    // if counter == -1, then you'll get an exception here
我会把信息还给你

java.lang.ArrayIndexOutOfBoundsException: -1
注意

private Request[] cache = new Request[M];

其中M==0仍然是一个有效的Java数组初始化,但不能向其中添加任何内容

由于实例变量初始化阶段,以下变量使用0初始化

缓存
初始化移动到构造函数中,以便在创建
算法
实例时初始化缓存:

/** Cache */
private Request[] cache;

public Algorithm(int M) { 
    this.M = M; 
    this.cache = new Request[M];  // set to Request[M]
}

这是Java中初始化块顺序的结果,如下所示:

  • 静态实例变量(第一类加载时仅运行一次)
  • 静态初始化块(第一类加载时仅运行一次)
  • 超级构造函数(如有)
  • 实例变量(每次创建新实例时运行)
    -->M并将缓存设置为0
  • 非静态init块(每次创建新实例时运行)
  • 构造函数
    -->M根据参数更新

  • 根据上述规则,您可以看到
    M
    最初默认为0。然后将
    M
    的值传递给
    cache
    ,该缓存被分配为0大小(一个空数组),从而导致ArrayIndexOutOfBoundsException(无论构造函数中为
    M
    分配了什么值,已经初始化的
    cache
    大小为0).

    由于实例变量初始化阶段的原因,以下变量用0初始化

    缓存
    初始化移动到构造函数中,以便在创建
    算法
    实例时初始化缓存:

    /** Cache */
    private Request[] cache;
    
    public Algorithm(int M) { 
        this.M = M; 
        this.cache = new Request[M];  // set to Request[M]
    }
    

    这是Java中初始化块顺序的结果,如下所示:

  • 静态实例变量(第一类加载时仅运行一次)
  • 静态初始化块(第一类加载时仅运行一次)
  • 超级构造函数(如有)
  • 实例变量(每次创建新实例时运行)
    -->M并将缓存设置为0
  • 非静态init块(每次创建新实例时运行)
  • 构造函数
    -->M根据参数更新


  • 根据上述规则,您可以看到
    M
    最初默认为0。然后将
    M
    的值传递给
    cache
    ,该值被分配为0大小(一个空数组),从而导致ArrayIndexOutOfBoundsException(无论构造函数中为
    M
    分配了什么值,已经初始化的
    cache
    的大小为0)。

    是否初始化了M变量?@wypipeprz当然是,在我的构造函数中,我有:public Algorithm(int M){this.M=M;},在main()中我设置了M=4;。首先,哇,你的变量名是不可描述的。第二,在将计数器用作索引之前,您是否尝试过打印它?@MirroredFate哈哈,从来没有想过我的变量名!嗯,在这种情况下,印刷总是个好主意,我会的,谢谢!你初始化了M变量吗?@wypiprz是的,当然,在我的构造函数中我有:public Algorithm(int M){this.M=M;},在main()中我设置了M=4;。首先,哇,你的变量名是不可描述的。第二,在将计数器用作索引之前,您是否尝试过打印它?@MirroredFate哈哈,从来没有想过我的变量名!嗯,在这种情况下,印刷总是个好主意,我会的,谢谢!这才是讨厌的东西!我在构造函数中初始化M,即公共算法(intm){this.M=M;},并在main()中设置M=4。因此,值4通过,M为4。我得到java.lang.ArrayIndexOutOfBoundsException:4。但是我试着给索引M-1=3赋值!可能您正在更改M值,但不是cache=newrequest[M]。我的意思是,如果cache=newrequest[M],仅更改M不会自动更改cache。也许,变量范围很复杂。你介意为算法和构造函数添加代码吗?哦,重要的区别。我已经设置了M=5(也就是说,我应该有从0到4的索引),我尝试在M-1=4分配一个值,我有一个ArrayIndexOutOfBoundsException:4!更累了,不是吗?或者它意味着什么?事实上我有一种感觉,你在一个超类中有一些其他的M:-)让我等待更多的代码来:-)这是令人厌倦的事情!我在构造函数中初始化M,即公共算法(intm){this.M=M;},并在main()中设置M=4。因此,值4通过,M为4。我得到java.lang.ArrayIndexOutOfBoundsException:4。但是我试着给索引M-1=3赋值!
    java.lang.ArrayIndexOutOfBoundsException: -1
    
    private Request[] cache = new Request[M];
    
    /** Max cache size */
    private int M; //set to 0 by default
    
    /** Cache */
    private Request[] cache = new Request[M]; //set to [] by default (an empty array)
    
    /** Cache */
    private Request[] cache;
    
    public Algorithm(int M) { 
        this.M = M; 
        this.cache = new Request[M];  // set to Request[M]
    }