2012-01-09 220 views
4

我使用這個類作爲我的鑰匙與哈希映射對象鍵

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()方法的HashMap問題在關鍵價值中。它顯示添加的最後一個鍵。

4.0 5.0 
4.0 5.0 
4.0 5.0 
4.0 5.0 
4.0 5.0 

我在哪裏出錯?

+0

感謝...的解決方法是添加DBL =新的雙[2];在將新值分配給數組之前... – 2012-01-09 22:59:15

回答

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

您不會複製setFactors和構造函數中的double[] factors數組。這就是爲什麼鍵類的所有實例最終會共享您在循環中修改的相同陣列。

你應該改變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使用數組的引用語義,因此每次通過循環時,都會更改數組中的值,並且所有更改都會反映在所有對象中。

換句話說,你確實有五個不同的對象,並且它們全都打印出來,但它們都引用相同的數組。

要解決此問題,請爲循環的每次迭代創建一個新數組。