Java - 数组索引超出范围 - Vector?

时间:2017-04-29 04:24:38

标签: java vector

我正在测试一个在向量中添加哈希对链表的方法。虽然,我遇到了IndexOutOfBounds,但我无法理解问题所在。

import java.util.*;

class HashPair<K, E> {
  K key;
  E element;
}

public class Test4<K, E> {
private Vector<LinkedList<HashPair<K, E>>> table;

public Test4(int tableSize) {
    if (tableSize <= 0)
        throw new IllegalArgumentException("Table Size must be positive");

    table = new Vector<LinkedList<HashPair<K, E>>>(tableSize);
}

public E put(K key, E element) {
    if (key == null || element == null)
        throw new NullPointerException("Key or element is null");

    int i = hash(key);
    LinkedList<HashPair<K, E>> onelist = table.get(i);
    ListIterator<HashPair<K, E>> cursor = onelist.listIterator();

    HashPair<K, E> pair;
    E answer = null;

    while (cursor.hasNext()) {
        pair = cursor.next();
        if (pair.key.equals(key)) {
            answer = pair.element;
            pair.element = element;
            return answer;
        }
    }

    pair = new HashPair<K, E>();
    pair.key = key;
    pair.element = element;
    onelist.addFirst(pair);
    return answer;

}

private int hash(K key) {
    return Math.abs(key.hashCode() % table.capacity());
}

public static void main(String[] args) {

    Test4<Integer, Integer> obj = new Test4<Integer, Integer>(10);

    obj.put(0, 10);
  }
}

我的编译器说问题就在这里:

LinkedList<HashPair<K, E>> onelist = table.get(i);

据我所知,我正在尝试获取i的表索引,这是从散列(K key)方法生成的散列值。那么在我的主要方法中,如果我将键设置为0作为示例?为什么指数超出范围?

这是例外

Exception in thread "main" 0java.lang.ArrayIndexOutOfBoundsException: 
Array index out of range: 0

at java.util.Vector.get(Vector.java:748)
at Test4.put(Test4.java:24)
at Test4.main(Test4.java:55)

2 个答案:

答案 0 :(得分:2)

这里的问题是你正在考虑向量的capacity是向量中的元素数量。这不是集合的capacity所代表的。

标准Java库中集合的capacity是该集合使用的内部数组的大小。但是,集合中的元素数量由size表示。

每当向此类集合添加/删除元素时,都会修改size属性。 不会影响集合capacity,除非需要调整内部数组的大小。

解决方案:将hash()修改为以下内容:

private int hash(K key) {
    return Math.abs(key.hashCode() % table.size());
}

在调用tablehash之前,请确保table.get向量包含至少一个元素。

我假设您正在使用存储桶创建HashMap的实现。如果您是,那么请考虑一下:如果不是任何存储桶,您如何在存储桶中存储值?在尝试get存储桶之前,您需要至少有一个存储桶

答案 1 :(得分:0)

您的代码似乎停留在第748行,即:

LinkedList<HashPair<K, E>> onelist = table.get(i);

说明Array index out of range: 0表示您在当时没有此类广告位时可以尝试在广告位0&#39; 0处获取对象。简而言之:你的向量是空的。通过查看代码,原因变得非常明显。调用Vector之前调用此table Test4.put()的唯一处理方法将在第15行得出结论:

table = new Vector<LinkedList<HashPair<K, E>>>(tableSize);

所以,是的,你正确地创建了一个对象并初始化了一个变量,你甚至指定了一个默认容量,但是你从未在全新的Vector中添加一些东西,并且这两个列表和向量都做了需要先填充手动填充内容。请记住,这个&#34;容量&#34;指的是这个Vector应该持有多少东西而不需要调整它在内部使用的数组的大小。它给我的印象是你正在尝试创建一个类,其对象具有类似HashMap的行为,但我不能围绕使用Vector {{1}的需要只有LinkedList s的单个集合应该足够KeyPair s,除非......等待,KeyPair方法做什么?哦......哦......哦,我明白你在那里做了什么。

所以,对,解决方案。正确创建hash()为空时,您需要填写它应该保留的内容。在这种情况下,它保存Vector的{​​{1}} s,所以让我们用足够的LinkedList来填充它,以保存您通过构造函数设置的容量。对构造函数的这种修改应该做的事情是:

KeyPair

这就是它。我甚至测试了它here只是为了确保它在我的补丁之后工作正常。

希望这会对你有所帮助。

PS: n 片段中拆分您的结构以加快搜索/存储速度?我喜欢这个主意。