2012-01-09 4 views
4

Я использую этот класс, как мой ключ к HashMap сHash Карта объекта Key

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

я добавил значения для сопоставления с помощью цикла

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

перекрываться hasCode() и Equals() проблема находится в ключевых значениях. Он отобразил последний добавленный ключ.

4.0 5.0 
4.0 5.0 
4.0 5.0 
4.0 5.0 
4.0 5.0 

Где я ошибаюсь?

+0

спасибо ... обходной путь, чтобы добавить ДВМ = новый двойной [2]; перед назначением новых значений массиву ... –

ответ

2

Если вы переместите объявление своего массива в цикл for, все будет идти так, как ожидалось. Проблема в том, что все ваши Design экземпляры имеют одинаковый массив.

for(int i=0; i<5; i++){ 
    double[] dbl = new double[2]; 
    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)); 
} 

Кроме того, ваш метод equals даст к некорректным результатам, когда у вас есть подкласс Design. Вместо использования instanceof сравните классы. Меняем

if (!(obj instanceof Design)) 
     return false; 

в

if (!(obj.getClass() == getClass())) 
    return false; 

Это, однако, не связан с вашей проблемой

3

Вы не копируете массив double[] factors в setFactors и конструкторе. Вот почему все экземпляры ключевого класса в конечном итоге используют один и тот же массив, который вы изменяете в цикле.

Вы должны изменить setFactors следующим образом:

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

Проблемы в том, что вы используете один и тот же массив дублей для всех случаев, которые вы создаете дизайн. Когда вы инициализируете следующие числа в основном цикле, вы снова меняете первый объект. Попробуйте это:

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

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

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

Или, если это будет иметь накладные расходы на производительность, что не приемлемо в вашем приложении, просто быть очень осторожным о том, как использовать массивы, передаваемые setFactors и возвращаемое значение getFactors.

2

Вы сделали только один объект массива. Java использует ссылочную семантику для массивов, поэтому каждый раз, когда вы проходите цикл, вы изменяете значения в массиве, а изменения отражаются во всех объектах Design.

Другими словами, у вас есть пять различных объектов Design, и они печатают их все, но все они ссылаются на один и тот же массив.

Чтобы исправить это, создайте новый массив для каждой итерации цикла.