2012-04-05 3 views
2

Я пытаюсь сохранить несколько значений для ключа в структуре данных, поэтому я использую MultiMap от Guava (Google Collection).Java MultiMap Not Recognizing Key

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() увеличивается, когда я ставлю что-то there.It также не происходит, когда ключи String вместо double[].

Любая идея, в чем проблема?

Edit: Большое спасибо Jon тарелочкам теперь я реализовал класс:

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. Это дает мне ошибку, если я положил @Override до метода equals. Любая идея, в чем проблема сейчас?

Спасибо :)

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-карты. – Raedwald

ответ

8

Вы используете массивы как ключи хэша. Это не сработает - Java не переопределяет hashCode и equals для массивов. (Класс Arrays предоставляет методы для этого, но он не поможет вам здесь.) По общему признанию, я ожидал, что он будет работать в этом конкретном случае, когда вы используете точные ссылки как для put, так и для containsKey. Когда я проверяю ваш код, он печатает true. Вы уверены, что можете воспроизвести его с точно своим кодом?

К примеру, в то время как я бы ожидать, что она работает на код, который вы дали, я не бы ожидать, что это работает:

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

Похоже, вы не должны быть действительно используя здесь double[] - вы должны создать класс Point, который имеет две переменные double и переопределяет equals и hashCode.

Кроме того, использование значений double в хэш-ключах - обычно - плохая идея, в силу природы двоичной арифметики с плавающей запятой. Это будет проблемой даже при использовании идеи Point выше ... это должно быть хорошо, если вам не нужно делать какие-либо арифметические действия (если вы просто копируете значения), но проявляйте большую осторожность ...

+1

@Tring: Я никогда не предлагал этого. См. Мое редактирование для альтернативы. –

+0

Спасибо ... Получил это :) – Tring

+0

Я реализовал то, что вы предложили, и все же у меня есть небольшая проблема. можете ли вы посмотреть? – Tring

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 
Смежные вопросы