【问题标题】:ArrayIndexOutOfBoundsException in my hashCode method [duplicate]我的 hashCode 方法中的 ArrayIndexOutOfBoundsException [重复]
【发布时间】:2016-06-06 08:50:08
【问题描述】:

首先,我的问题是关于 Java 中的 HashSet,我遇到的问题是:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2
    at Main$State.hashCode(Main.java:92)
    at java.util.HashMap.hash(HashMap.java:338)
    at java.util.HashMap.containsKey(HashMap.java:595)
    at java.util.HashSet.contains(HashSet.java:203)
    at Main.uniform_cost_search(Main.java:128)
    at Main.main(Main.java:109)

我有一个类名State,它有变量:int cost, int[3] parent, byte[22] encode

import java.awt.Point;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Set;

public class Main {

    static class State {
        public int cost;
        public int[] parent = new int[3];
        public byte[] encode = new byte[22];

        public State(int cost, int[] parent, byte[] encode){
            this.cost=cost;
            for (int i=0; i<3; i++)
                this.parent[i]=parent[i];
            for (int i=0; i<22; i++)
                this.encode[i]=encode[i];
        }

        public void printState(){
            System.out.printf(" cost=%d,parent=[%d,%d,%d],[", 
                    cost, parent[0], parent[1], 
                    parent[2]);
            for (int i=0; i<22; i++)
                if (i%2==0)
                    System.out.printf("%d.", encode[i]);
                else if (i==21)
                    System.out.printf("%d", encode[i]);
                else
                    System.out.printf("%d ", encode[i]);
            System.out.printf("]\n");
        }

        // for HashSet
        @Override
        public boolean equals(Object o){
            if (o instanceof State){
                State other = (State) o;
                for (byte i=0; i<22; i++)
                    if (encode[i] != other.encode[i])
                        return false;
                return true;
            }
            return false;
        }       

        // for HashSet
        @Override
        public int hashCode() {
            int re=0;
            for (byte temp : encode)
                re += encode[temp]*encode[temp]*encode[temp];
            return re;
        }

    }

所以,我使用 hashCode() 函数的目的是对 encode[] 数组进行哈希处理,通过 encode[] 数组的值使 HashSet 不同
在我的主函数中,当我创建一个主函数时:

    public static void main(String[] args) {
        System.out.println("hello world");
        Set<State> visited= new HashSet<State>();

        byte[] destination = new byte[22];
        destination[0]=-2;destination[1]=4; 
        State goldState = new State(0, new int[]{0,0,0}, destination);

        visited.add(goldState);
        if (visited.contains(goldState))
            System.out.printf("contain goldState\n");       
    }

运行代码,我收到错误。
我非常感谢您的建议。

运行方法goldState.printState(),输出等价于数据int cost,int[3] parent,byte[22] encode为:

cost=0,parent=[0,0,0],[-2.4 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0]

【问题讨论】:

  • @JimGarrison 的回答解决了您的直接问题,但您可能需要考虑使用 Arrays.hashCode(encode) 而不是自己编写数组哈希算法。
  • @AndyTurner:亲爱的安迪,我很想知道更多。我所做的方式是我唯一知道的方式,所以你是对的,这可能不是一个好方法。您能否针对我的情况给出具体的解决方案?否则,您能否提供一些参考或提示,以便我了解更多信息。我会很感激 :) 我想知道你的建议是:“@Override public int hashCode() { return Arrays.hashCode(encode); }”
  • 我并没有声称 Arrays.hashCode(byte[]) 产生的哈希值质量上乘;仅仅因为它是一种合理的通用算法,并且更易于使用(一行而不是自己编写)。

标签: java hash


【解决方案1】:

问题出在:

    public int hashCode() {
        int re=0;
        for (byte temp : encode)
            re += encode[temp]*encode[temp]*encode[temp];
        return re;
    }

for 循环遍历数组encode 并为您提供,而不是索引。因此下一行应该是

re += temp*temp*temp;

您实际编写的代码是尝试使用 作为索引,这会导致在尝试使用 -2(值)作为索引时出错。

【讨论】:

  • 嗨`。非常感谢您的出色回答,Jim Garrison 先生 :)
猜你喜欢
  • 2014-10-17
  • 2021-05-20
  • 1970-01-01
  • 1970-01-01
  • 2019-02-18
  • 2017-07-22
  • 1970-01-01
  • 2015-11-08
  • 2014-11-17
相关资源
最近更新 更多