Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hash Map Object Key

Tags:

java

hashmap

I'm using this class as my key to Hashmap with overriden hasCode() and equals()

public class Design {
private double[] factors = null;

public double[] getFactors() {
    return factors;
}

public void setFactors(double[] factors) {
    this.factors = factors;
}

public Design(double[] factors) {
    this.factors = factors;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + Arrays.hashCode(factors);
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (!(obj instanceof Design))
        return false;
    Design other = (Design) obj;
    if (!Arrays.equals(factors, other.factors))
        return false;
    return true;
}

I added values to map using a loop

 public static void main(String[] args) {

    Map<Design, Double> map = new HashMap<Design, Double>();

    double[] dbl = new double[2];

    for(int i=0; i<5; i++){
        for(int j=0; j<2; j++){
            System.out.println(j+i);
            dbl[j] = j+i;
        }
        Design des = new Design(dbl);
        map.put(des, Double.valueOf(i));
    }

    for(Design d: map.keySet()){
        System.out.println(d.getFactors()[0] + "\t" + d.getFactors()[1]);
    }

    for(double d: map.values()){
        System.out.println(d);
    }
}

The problem is in the key values. It displayed the last key added.

4.0 5.0
4.0 5.0
4.0 5.0
4.0 5.0
4.0 5.0

Where am I getting wrong?

like image 304
JR Galia Avatar asked Dec 28 '22 08:12

JR Galia


2 Answers

You are not copying your double[] factors array in the setFactors and the constructor. That is why all instances of the key class end up sharing the same array that you modify in the loop.

You should change setFactors as follows:

public void setFactors(double[] factors) {
    this.factors = new double[factors];
    System.arrayCopy(factors, 0, this.factors, 0, factors.length);
}

public Design(double[] factors) {
    setFactors(factors);
}
like image 96
Sergey Kalinichenko Avatar answered Jan 08 '23 18:01

Sergey Kalinichenko


The problem is you're using the same array of doubles for all the instances you create of Design. When you initialize the next numbers in the main loop, you're modifying the first object again. Try this:

public double[] getFactors() {
    return factors.clone();
}

public void setFactors(double[] factors) {
    this.factors = factors.clone();
}

public Design(double[] factors) {
    setFactors(factors);
}

Or, if that would have a performance overhead that's not acceptable in your application, just be very careful about how you use the arrays passed to setFactors and the return value of getFactors.

like image 22
Boann Avatar answered Jan 08 '23 18:01

Boann