Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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
Java 为什么我在这里有一个IndexOutOfBoundsException?_Java - Fatal编程技术网

Java 为什么我在这里有一个IndexOutOfBoundsException?

Java 为什么我在这里有一个IndexOutOfBoundsException?,java,Java,我在下面的replaceValue方法中引发了一个索引越界异常,我不知道原因。 [无效,(10,4)、(52,3)、(39,9)、(78,7)、(63,8)、(42,2)、(50411)] 重置价值测试:411 尺寸=7 [无效,(10,4)、(52,3)、(39,9)、(78,7)、(63,8)、(42,2)、(50101)] 去除试验:(10,4) [无效,(39,9)、(52,3)、(42,2)、(78,7)、(63,8)、(50101)] 尺寸=6 我尝试在这里再次替换该值,并得到一个错

我在下面的replaceValue方法中引发了一个索引越界异常,我不知道原因。

[无效,(10,4)、(52,3)、(39,9)、(78,7)、(63,8)、(42,2)、(50411)]

重置价值测试:411 尺寸=7

[无效,(10,4)、(52,3)、(39,9)、(78,7)、(63,8)、(42,2)、(50101)]

去除试验:(10,4)

[无效,(39,9)、(52,3)、(42,2)、(78,7)、(63,8)、(50101)]

尺寸=6

我尝试在这里再次替换该值,并得到一个错误

package heappriorityqueue;
import java.util.*;
public class HeapPriorityQueue<K,V> {
protected ArrayList<Entry<K,V>> heap;
protected Comparator<K> comp;
int size = 0;
protected static class MyEntry<K,V> implements Entry<K,V> {
    protected K key;
    protected V value;
    protected int loc;
    public MyEntry(K k, V v,int i) {key = k; value = v;loc =i;}
    public K getKey() {return key;}
    public V getValue() {return value;}
    public int getLoc(){return loc;}
    public String toString() {return "(" + key + "," + value + ")";}
    void setKey(K k1) {key = k1;}
    void setValue(V v1) {value = v1;}
    public void setLoc(int i) {loc = i;}
}
public HeapPriorityQueue() {
    heap = new ArrayList<Entry<K,V>>();
    heap.add(0,null);
    comp = new DefaultComparator<K>();
}
public HeapPriorityQueue(Comparator<K> c) {
    heap = new ArrayList<Entry<K,V>>();
    heap.add(0,null);
    comp = c;
}
public int size() {return size;}
public boolean isEmpty() {return size == 0; }
public Entry<K,V> min() throws EmptyPriorityQueueException {
    if (isEmpty())
        throw new EmptyPriorityQueueException("Priority Queue is Empty");
    return heap.get(1);
}
public Entry<K,V> insert(K k, V v) {
    size++;
    Entry<K,V> entry = new MyEntry<K,V>(k,v,size);
    heap.add(size,entry);
    upHeap(size);
    return entry;
}
public Entry<K,V> removeMin() throws EmptyPriorityQueueException {
    if (isEmpty())
        throw new EmptyPriorityQueueException("Priority Queue is Empty");
    if (size == 1)
        return heap.remove(1);
    Entry<K,V> min = heap.get(1);
    heap.set(1, heap.remove(size));
    size--;
    downHeap(1);
    return min;
}

public V replaceValue(Entry<K,V> e, V v) throws InvalidEntryException,
        EmptyPriorityQueueException {
// replace the value field of entry e in the priority
// queue with the given value v, and return the old value

This is where I am getting the IndexOutOfBounds exception, on heap.get(i);

if (isEmpty()){
        throw new EmptyPriorityQueueException("Priority Queue is Empty.");
    }
    checkEntry(e);
    int i = e.getLoc();
    Entry<K,V> entry=heap.get(((i)));
    V oldVal = entry.getValue();
    K key=entry.getKey();
    Entry<K,V> insert = new MyEntry<K,V>(key,v,i);
    heap.set(i, insert);
    return oldVal;
}

public K replaceKey(Entry<K,V> e, K k) throws InvalidEntryException,
        EmptyPriorityQueueException, InvalidKeyException {
    // replace the key field of entry e in the priority
    // queue with the given key k, and return the old key
    if (isEmpty()){
        throw new EmptyPriorityQueueException("Priority Queue is Empty.");
    }
    checkKey(k);
    checkEntry(e);
    K oldKey=e.getKey();
    int i = e.getLoc();
    Entry<K,V> entry = new MyEntry<K,V>(k,e.getValue(),i);
    heap.set(i,entry);
    downHeap(i);
    upHeap(i);
    return oldKey;
}

public Entry<K,V> remove(Entry<K,V> e) throws InvalidEntryException,
        EmptyPriorityQueueException{
    // remove entry e from priority queue and return it
    if (isEmpty()){
        throw new EmptyPriorityQueueException("Priority Queue is Empty.");
    }
    MyEntry<K,V> entry = checkEntry(e);
    if (size==1){
        return heap.remove(size--);
    }
    int i = e.getLoc();
    heap.set(i, heap.remove(size--));
    downHeap(i);
    return entry;
}

protected void upHeap(int i) {
    while (i > 1) {
        if (comp.compare(heap.get(i/2).getKey(), heap.get(i).getKey()) <= 0)
            break;
        swap(i/2,i);
        i = i/2;
    }
}
protected void downHeap(int i) {
    int smallerChild;
    while (size >= 2*i) {
        smallerChild = 2*i;
        if ( size >= 2*i + 1)
            if (comp.compare(heap.get(2*i + 1).getKey(), heap.get(2*i).getKey()) < 0)
                smallerChild = 2*i+1;
        if (comp.compare(heap.get(i).getKey(), heap.get(smallerChild).getKey()) <= 0)
            break;
        swap(i, smallerChild);
        i = smallerChild;
    }
}
protected void swap(int j, int i) {
    heap.get(j).setLoc(i);
    heap.get(i).setLoc(j);
    Entry<K,V> temp;
    temp = heap.get(j);
    heap.set(j, heap.get(i));
    heap.set(i, temp);

}
public String toString() {
    return heap.toString();
}
protected MyEntry<K,V> checkEntry(Entry<K,V> ent) 
    throws InvalidEntryException 
  {
    if(ent == null || !(ent instanceof MyEntry))
      throw new InvalidEntryException("Invalid entry.");
    return (MyEntry)ent;
  }
protected void checkKey(K key) throws InvalidKeyException{
    try{comp.compare(key,key);}
    catch(Exception e){throw new InvalidKeyException("Invalid key.");}
}
包heappriorityqueue;
导入java.util.*;
公共类HeapPriorityQueue{
受保护的ArrayList堆;
受保护比较器;
int size=0;
受保护的静态类MyEntry实现条目{
受保护的K密钥;
保护V值;
受保护的内部位置;
公共MyEntry(kk,vv,inti){key=K;value=V;loc=i;}
public K getKey(){return key;}
public V getValue(){return value;}
public int getLoc(){return loc;}
公共字符串toString(){return“(“+key+”,“+value+”);}
void setKey(kk1){key=k1;}
void setValue(vv1){value=v1;}
公共无效setLoc(inti){loc=i;}
}
公共HeapPriorityQueue(){
heap=newarraylist();
heap.add(0,null);
comp=新的DefaultComparator();
}
公共HEAPPERRITYQUEUE(比较器c){
heap=newarraylist();
heap.add(0,null);
comp=c;
}
public int size(){return size;}
公共布尔值isEmpty(){return size==0;}
public Entry min()引发EmptyPriorityQueueException{
if(isEmpty())
抛出新的EmptyPriorityQueueException(“优先级队列为空”);
返回heap.get(1);
}
公共条目插入(K,V){
大小++;
条目=新的MyEntry(k、v、大小);
添加(大小、条目);
尺寸;
返回条目;
}
public Entry removeMin()引发EmptyPriorityQueueException{
if(isEmpty())
抛出新的EmptyPriorityQueueException(“优先级队列为空”);
如果(大小==1)
返回堆。删除(1);
Entry min=heap.get(1);
heap.set(1,heap.remove(size));
大小--;
下堆(1);
返回最小值;
}
public V replaceValue(条目e,V)抛出InvalidEntryException,
EmptyPriorityQueueException{
//替换优先级中条目e的值字段
//使用给定值v排队,并返回旧值
这就是我在heap.get(I)上获取IndexOutOfBounds异常的地方;
if(isEmpty()){
抛出新的EmptyPriorityQueueException(“优先级队列为空”);
}
支票分录(e);
int i=e.getLoc();
Entry=heap.get((i));
V oldVal=entry.getValue();
K key=entry.getKey();
条目插入=新的MyEntry(键,v,i);
heap.set(i,insert);
返回oldVal;
}
public K replaceKey(条目e,K)抛出InvalidEntryException,
EmptyPriorityQueueException,InvalidKeyException{
//替换优先级中条目e的键字段
//使用给定的密钥k排队,并返回旧密钥
if(isEmpty()){
抛出新的EmptyPriorityQueueException(“优先级队列为空”);
}
检查键(k);
支票分录(e);
K oldKey=e.getKey();
int i=e.getLoc();
Entry=newmyentry(k,e.getValue(),i);
set(i,条目);
下堆(i);
(i);
返回oldKey;
}
公共条目删除(条目e)引发InvalidEntryException,
EmptyPriorityQueueException{
//从优先级队列中删除条目e并将其返回
if(isEmpty()){
抛出新的EmptyPriorityQueueException(“优先级队列为空”);
}
MyEntry条目=支票条目(e);
如果(大小==1){
返回堆。删除(大小--);
}
int i=e.getLoc();
heap.set(i,heap.remove(size--));
下堆(i);
返回条目;
}
受保护的空区(int i){
而(i>1){
if(comp.compare(heap.get(i/2).getKey(),heap.get(i).getKey())=2*i){
smallerChild=2*i;
如果(尺寸>=2*i+1)
if(comp.compare(heap.get(2*i+1).getKey(),heap.get(2*i).getKey())<0)
smallerChild=2*i+1;

如果(comp.compare(heap.get(i).getKey(),heap.get(smallerChild).getKey())将条目的数组索引保存在条目本身中。但是在
remove()
方法中,您不会更改它。您必须为所有更改位置的元素更改该索引,否则在进一步的remove调用中会删除错误的元素


在您的示例中,
(50101)
最初有索引6。此值在删除后保留,因此如果您尝试替换它,它仍会尝试访问索引6(因为
int i=e.getLoc();
)它已经不存在了。

请发布堆栈跟踪。发布代码和堆栈跟踪的相关部分。我不会首先将索引保存在元素中。这是一个非常糟糕的设计,因为索引管理的责任不仅从数组移动到元素,而且是重复的。您应该随时查找元素的索引你需要它。我不能在这个赋值中使用indexOf,否则我会使用它。嗯,我以为我已经用交换方法解决了这个问题,但我现在不确定哪里出了问题。你必须编写自己的indexOf,在其中迭代数组,并将每个元素与你要查找的元素进行比较。
HeapPriorityQueue<Integer,Integer> testPQ = new HeapPriorityQueue<Integer,Integer>();
    System.out.print("[");
    int x;
    for (int i = 0; i < 10; i++) {
        x = (int) (100 * Math.random());
        System.out.print(" " + x);
        testPQ.insert(x,i);


    }
    System.out.println("]");

    System.out.println(testPQ);
    for (int i = 0; i < 5; i++) {
        System.out.println(testPQ.removeMin());
        System.out.println(testPQ);
    }

    Entry e = testPQ.insert(10, 4);
    System.out.println("insertion of "+e);
    System.out.println(testPQ);
    System.out.println("size="+testPQ.size);
    System.out.println(e.getKey());
    Entry r = testPQ.insert(50, 411);
    System.out.println("insertion of "+r);

    System.out.println("size="+testPQ.size);
    System.out.println(testPQ);
    System.out.println("replacement value test" + 
            testPQ.replaceValue(r, 101));

    System.out.println("size="+testPQ.size);
    System.out.println(testPQ);
    System.out.println("removal test:"+testPQ.remove(e));
    System.out.println(testPQ);
    System.out.println("replacement value test" + 
            testPQ.replaceValue(r, 201));
    System.out.println("replacement value test" + 
            testPQ.replaceValue(r, 301));
    System.out.println("replacement value test" + 
            testPQ.replaceValue(r, 401));
    System.out.println("size="+testPQ.size);
    System.out.println(testPQ);

    Entry k = testPQ.min();
    System.out.println("replacement key test:"+testPQ.replaceKey(k,77)
            +" w/77");
    System.out.println(testPQ);
    Entry v = testPQ.min();
    System.out.println("replacement key test:"+testPQ.replaceKey(v,6)+
            " w/6");
    System.out.println(testPQ);
    System.out.println("removal test:"+testPQ.remove(v));
    System.out.println(testPQ);

run:
[ 17 86 13 52 98 4 9 25 6 75]
[null, (4,5), (6,8), (9,6), (25,7), (75,9), (17,0), (13,2), (86,1), (52,3), (98,4)]
(4,5)
[null, (6,8), (25,7), (9,6), (52,3), (75,9), (17,0), (13,2), (86,1), (98,4)]
(6,8)
[null, (9,6), (25,7), (13,2), (52,3), (75,9), (17,0), (98,4), (86,1)]
(9,6)
[null, (13,2), (25,7), (17,0), (52,3), (75,9), (86,1), (98,4)]
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 7, Size: 7
(13,2)
[null, (17,0), (25,7), (86,1), (52,3), (75,9), (98,4)]
(17,0)
[null, (25,7), (52,3), (86,1), (98,4), (75,9)]
insertion of (10,4)
[null, (10,4), (52,3), (25,7), (98,4), (75,9), (86,1)]
size=6
10
insertion of (50,411)
size=7
[null, (10,4), (52,3), (25,7), (98,4), (75,9), (86,1), (50,411)]
replacement value test411
size=7
[null, (10,4), (52,3), (25,7), (98,4), (75,9), (86,1), (50,101)]
removal test:(10,4)
[null, (25,7), (52,3), (50,101), (98,4), (75,9), (86,1)]
at java.util.ArrayList.rangeCheck(ArrayList.java:604)
at java.util.ArrayList.get(ArrayList.java:382)
at heappriorityqueue.HeapPriorityQueue.replaceValue(HeapPriorityQueue.java:283)
at heappriorityqueue.Main.main(Main.java:55)