簡體   English   中英

為什么會出現這個ArrayIndexOutOfBounds異常?

[英]Why is this ArrayIndexOutOfBounds exception occurring?

我正在嘗試使用哈希表實現一個字典(不使用Java提供的哈希表類,而是從頭開始)。 下面是我的Dictionary類的insert()方法,用於將元素插入到特定數組位置中包含的鏈表中。

我正在運行一個提供的測試程序來確定我的Dictionary類是否有效,但是我遇到了一個ArrayIndexOutOfBoundsException: -5980到達某個點時。 以下是特定測試。 為什么這個例外會出現? (如果需要,我可以提供更多代碼!)

插入:

public int insert(DictEntry pair) throws DictionaryException {
    String entryConfig = pair.getConfig();
    int found = find(entryConfig);

    if (found != -1) {
        throw new DictionaryException("Pair already in dictionary.");
    }

    int entryPosition = hash(entryConfig);

    if (dict[entryPosition] == null) { //Dictionary.java:54
        LinkedList<DictEntry> list = new LinkedList<DictEntry>();
        dict[entryPosition] = list;
        list.add(pair);
        return 0;
    } else {
        LinkedList<DictEntry> list = dict[entryPosition];
        list.addLast(pair);
        return 1;
    }
}

考試:

    // Test 7: insert 10000 different values into the Dictionary
    // NOTE: Dictionary is of size 9901
    try {
        for (int i = 0; i < 10000; ++i) {
            s = (new Integer(i)).toString();
            for (int j = 0; j < 5; ++j) s += s;
            collisions += dict.insert(new DictEntry(s,i)); //TestDict.java:69
        }
        System.out.println("   Test 7 succeeded");
    } catch (DictionaryException e) {
        System.out.println("***Test 7 failed");
    }

異常堆棧跟蹤:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -5980
    at Dictionary.insert(Dictionary.java:54)
    at TestDict.main(TestDict.java:69)

哈希函數:

private int hash(String config) {
int expBase = 41;
int exp;
int ASCIIChar;
int hashedConfig = 0;

    for (int i = 0; i < config.length(); i++) {
        ASCIIChar = (int)config.charAt(i);
        exp = (int)Math.pow(expBase, i);
        hashedConfig = hashedConfig + (ASCIIChar * exp);
    }

    hashedConfig = hashedConfig % dictSize;
    return hashedConfig;
}

你的

exp = (int)Math.pow(expBase, i);
hashedConfig = hashedConfig + (ASCIIChar * exp);

將溢出整數范圍,因此生成負數。 添加Math.abs返回hashedConfig之前。

您可能應該分析它如何影響哈希函數的分布。

正確 - 正如所懷疑的那樣,問題在於hash() 這個:

hashedConfig = hashedConfig % dictSize;

......不保證會是積極的。 如果它開頭是負面的,你仍然會得到一個負數。 你可以使用:

hashedConfig = Math.abs(hashedConfig % dictSize);

要么:

hashedConfig = hashedConfig % dictSize;
if (hashedConfig < 0) {
    hashedConfig += dictSize;
}

兩者都會在正確的范圍內獲得價值,但您可能會發現后者更均勻。

請注意,您的散列代碼效率也非常低。 你完全不清楚為什么你不使用String.hashCode()來開始。 (您仍然需要將任意32位整數轉換為數組元素范圍內的值,但至少散列本身會更快。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM