0

To begin with, my problem is about HashSet in Java, and the problem that I got is:

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)

I have a class name State, it has variables: 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;
        }

    }

So, my purpose for hashCode() function is that Hash the encode[] array, make the HashSet different by values of encode[] array
In my main function, when I created a main function:

    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");       
    }

Running code and I receive the error.
I am very grateful for suggestions.

Running the method goldState.printState(), the output equivalent to the data int cost, int[3] parent, byte[22] encode is:

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]
Raedwald
  • 46,613
  • 43
  • 151
  • 237
NNguyen
  • 113
  • 1
  • 6
  • 1
    @JimGarrison's answer fixes your immediate issue, but you might want to consider using `Arrays.hashCode(encode)` instead of making up your own array hashing algorithm. – Andy Turner Feb 24 '16 at 07:36
  • @AndyTurner: Dear Andy, I would love to know more about it. The way I did is the only way I know, so you are correct, it may not be a good way. Could you give specific solution to my case? Otherwise, could you give some reference or hint so I can learn more. I would be grateful :) I wonder your sugegstion is: "@Override public int hashCode() { return Arrays.hashCode(encode); }" – NNguyen Feb 24 '16 at 07:44
  • I am not making any claims of superior quality of the hash resulting from [`Arrays.hashCode(byte[])`](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/Arrays.java#Arrays.hashCode%28byte%5B%5D%29); merely that it is a reasonable general algorithm, and easier to use (one line vs writing your own). – Andy Turner Feb 24 '16 at 07:49

1 Answers1

3

The problem is in:

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

The for loop is iterating over the array encode and providing you the values, not the indexes. Therefore the next line should be

re += temp*temp*temp;

What you have actually coded is attempting to use the values as indexes, which results in the error when attempting to use -2 (a value) as an index.

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190