简体   繁体   English

Java MultiMap 无法识别密钥

[英]Java MultiMap Not Recognizing Key

I'm trying to store multiple values for a key in a data structure so I'm using Guava (Google Collection)'s MultiMap.我试图在数据结构中为一个键存储多个值,所以我使用的是 Guava (Google Collection) 的 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));

and it returns false.它返回 false。

Note: Key-values are being stored in the multimap as the destinations.size() increases when I put something there.It also does not happen when keys are String instead of double[] .注意:当我把东西放在那里时,随着destinations.size()的增加,键值被存储在多映射中。当键是String而不是double[]时,它也不会发生。

Any idea what the problem is?知道问题是什么吗?

Edit: Many thanks to Jon Skeet I now implemented the class:编辑:非常感谢 Jon Skeet 我现在实现了 class:

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

And now I have a new problem.现在我有一个新问题。 This is how I'm using it:这就是我使用它的方式:

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

The first one returns true, the second one returns false.第一个返回真,第二个返回假。 It gives me an error if I put @Override before the equals method.Any Idea what the problem is now?如果我将@Override放在equals方法之前,它会给我一个错误。知道现在的问题是什么吗?

Thanks:)谢谢:)

Edit2: It now behaves exactly as expected when I changed equals to this: 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);
    }
}

Thanks everyone.感谢大家。

You're using arrays as the hash keys.您正在使用arrays作为 hash 密钥。 That's not going to work - Java doesn't override hashCode and equals for arrays. (The Arrays class provides methods to do this, but it's not going to help you here.) Admittedly I'd expect it to work in this specific case, where you're using the exact same reference for both put and containsKey ... When I test your code, it prints true .那是行不通的——Java 不会覆盖hashCode并且equals arrays。( Arrays class 提供了执行此操作的方法,但它不会在这里帮助你。)诚然,我希望它能在这种特定情况下工作,您对putcontainsKey使用完全相同的引用的地方...当我测试您的代码时,它会打印true Are you sure you can reproduce it with exactly your code?确定你可以用你的代码重现它吗?

For example, while I'd expect it to work for the code you've given, I wouldn't expect this to work:例如,虽然我希望它适用于您提供的代码,但我希望它起作用:

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

It sounds like you shouldn't really be using double[] here - you should create a Point class which has two double variables, and overrides equals and hashCode .听起来你真的不应该在这里使用double[] - 你应该创建一个Point class 它有两个double变量,并覆盖equalshashCode

Additionally, using double values in hash keys is usually a bad idea anyway, due to the nature of binary floating point arithmetic.此外,由于二进制浮点运算的性质,在 hash 键中使用double精度值通常不是一个好主意。 That's going to be a problem even using the Point idea above... it should be okay if you don't need to actually do any arithmetic (if you're just copying values around) but take great care...即使使用上面的Point想法,这也会成为一个问题......如果你不需要实际做任何算术(如果你只是复制值)应该没问题,但要非常小心......

The problem is that you cannot hash "equal" arrays and get the same result each time.问题是你不能 hash “等于” arrays 并且每次都得到相同的结果。 For example:例如:

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

will result something like会产生类似的结果

306344348
1211154977

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM