2012-04-05 70 views
2

我試圖在數據結構中存儲一個密鑰的多個值,所以我使用的是Guava(Google集合)的MultiMap。Java MultiMap無法識別密鑰

Multimap<double[], double[]> destinations = HashMultimap.create(); 
destinations = ArrayListMultimap.create(); 

double[] startingPoint = new double[] {1.0, 2.0}; 
double[] end = new double[] {3.0, 4.0}; 
destinations.put(startingPoint, end); 

System.out.println(destinations.containsKey(startingPoint)); 

它返回false。

注意:鍵值存儲在multimap中,因爲destinations.size()在我放置某些東西時增加。當鍵爲String而不是double[]時,也不會發生鍵值。

任何想法是什麼問題?

編輯:非常感謝喬恩斯基特我現在實現的類:

class Point { 

    double lat; 
    double lng; 

    public boolean equals(Point p) { 

     if (lat == p.lat && lng == p.lng) 
      return true; 
     else 
      return false; 
    } 

    @Override 
    public int hashCode() { 

     int hash = 29; 
     hash = hash*41 + (int)(lat * 100000); 
     hash = hash*41 + (int)(lng * 100000); 

     return hash; 
    } 

    public Point(double newlat, double newlng) { 
     lat = newlat; 
     lng = newlng; 
    } 
} 

而且現在我有一個新的問題。這是我如何使用它:

Multimap<Point, Point> destinations = HashMultimap.create(); 
destinations = ArrayListMultimap.create(); 

Point startingPoint = new Point(1.0, 2.0); 
Point end = new Point(3.0, 4.0); 
destinations.put(startingPoint, end); 

System.out.println(destinations.containsKey(startingPoint)); 
System.out.println(destinations.containsKey(new Point(1.0, 2.0))); 

第一個返回true,第二個返回false。它給了我一個錯誤,如果我把@Overrideequals方法之前。任何想法現在是什麼問題?

謝謝:)

EDIT2:現在的行爲完全如預期,當我改變equals這樣:

@Override 
public boolean equals(Object p) { 

    if (this == p) 
     return true; 
    else if (!(p instanceof Point)) 
     return false; 
    else { 
     Point that = (Point) p; 
     return (that.lat == lat) && (that.lng == lng); 
    } 
} 

謝謝大家。

+0

有一個[相關問題](http://stackoverflow.com/questions/16839182/can-a-java-array-be- used-as-a-hashmap-key)用於普通Java「Map」情況。 – Raedwald 2015-02-26 12:57:39

回答

8

您正在使用陣列作爲散列鍵。這不起作用 - Java不會覆蓋數組的hashCodeequals。 (Arrays類提供了這樣做的方法,但它不會幫你在這裏。)不出所料,我希望它在這種特定情況下工作,其中你使用完全相同的參考putcontainsKey。 ..當我測試你的代碼時,它打印true。你確定你可以用正確你的代碼重現嗎?

例如,雖然我希望它爲你提供了代碼工作,我不會想到這個工作:

// Logically equal array, but distinct objects 
double[] key = (double[]) startingPoint.clone(); 
System.out.println(destinations.containsKey(key)); 

這聽起來像你真不該使用double[]在這裏 - 你應該創建一個Point類有兩個double變量,並覆蓋equalshashCode

此外,使用double散列鍵值是通常無論如何,由於二進制浮點運算的本質,無論如何。這是怎麼回事,即使使用上述Point想法是一個問題......它應該是好的,如果你不需要實際做任何運算(如果你只是複製周圍值),但會非常謹慎......

+1

@Tring:我從來沒有這樣說過。看到我的編輯替代。 – 2012-04-05 12:57:03

+0

謝謝...明白了:) – Tring 2012-04-05 13:00:20

+0

我實施了你的建議,並且還有一個小問題。你能看看嗎? – Tring 2012-04-05 13:51:27

1

問題是你不能散列「平等」的數組,每次都得到相同的結果。例如:

public static void main(String[] args) { 
    System.out.println(new double[]{1.0, 2.0}.hashCode()); 
    System.out.println(new double[]{1.0, 2.0}.hashCode()); 
} 

會導致類似

306344348 
1211154977