-1

我定义了一个 Point 类,它表示整数格上的一个点。我已经重写了 hashCode() 和 equals(Object) 的方法。

当对坐标值 >= 128 的点使用 HashMap.put(Point, Double) 时,HashMap 似乎没有做任何事情。没有抛出错误,但尝试从 HashMap 访问点将导致找不到密钥。我在 INTEGER.MAX_VALUE 之下,并且有足够的可用内存。

这是我的点课:

import java.util.ArrayList;

public class Point {
    protected int dimension;
    protected ArrayList<Integer> coordinates;

    public Point(int[] coordinates){
        this.coordinates = convertArray(coordinates);
        dimension = coordinates.length;
    }

    private ArrayList<Integer> convertArray(int[] array){
        ArrayList<Integer> newArray = new ArrayList<Integer>();
        for(int i = 0; i < array.length; i++){
            newArray.add(array[i]);
        }
        return newArray;
    }

    @Override
    public int hashCode(){
        // Some arbitrary quick hash
        return coordinates.get(0);
    }

    @Override
    public boolean equals(Object o){
        Point p = (Point)o;
        if(dimension != p.coordinates.size())
            return false;
        for(int i = 0; i < p.coordinates.size(); i++){
            if(coordinates.get(i) != p.coordinates.get(i)){
                return false;
            }
        }
        return true;
    }
}

和我跑的测试:

import java.util.*;
public class random {

    public static void main(String[] args) {
        HashMap<Point, Double> weight = new HashMap<Point, Double>((int)(150 * 150 * .75 + 1));
        for(int i = 0; i < 150; i++){
            for(int j = 0; j < 150; j++){
                int [] tmpArray = {i, j};
                weight.put(new Point(tmpArray), Math.random());
            }
        }

        for(int i = 0; i < 150; i++){
            for(int j = 0; j < 150; j++){
                int [] tmpArray = {i, j};
                if(weight.get(new Point(tmpArray)) == null){
                    System.out.println("[" + i + ", " + j + "]: ");
                    System.out.println(weight.containsKey(new Point(tmpArray)));
                }
            }
        }
    }
}

任何想法都会有所帮助。谢谢!

4

1 回答 1

0
@Override
    public boolean equals(Object o){
        Point p = (Point)o;
        if(dimension != p.coordinates.size())
            return false;
        for(int i = 0; i < p.coordinates.size(); i++){
            if(coordinates.get(i) != p.coordinates.get(i)){
                return false;
            }
        }
        return true;
    }

equals()当您将必须使用的对象equals与观察相等性进行比较时,您的实现很糟糕,而不是如果==它们指向相同的位置 (!=)。

Integer是一个对象,所以你必须使用。有时对相同的值equals==的很好,因为它们被缓存(-128 到 127)。

例子:

Integer a = 1000, b = 1000;  
System.out.println(a == b); // false  
Integer c = 100, d = 100;  
System.out.println(c == d); // true
Integer e=5 , f= new Integer(5);
System.out.println(e == f) // false

而不是循环你的列表,你可以简单地使用提供的列表方法 equals()

当且仅当指定的对象也是一个列表,两个列表具有相同的大小,并且两个列表中所有对应的元素对都相等时,才返回 true

此外,您不应该Keyhash valued map可变对象中使用 as 。 可变哈希映射键危险吗?

如果一个对象的 hashCode() 值可以根据它的状态而改变,那么我们在使用这些对象作为基于哈希的集合中的键时必须小心,以确保当它们被用作哈希键时我们不允许它们的状态发生变化. 所有基于散列的集合都假定对象的散列值在用作集合中的键时不会改变。如果键的哈希码在集合中时发生更改,则可能会出现一些不可预测和令人困惑的后果。

于 2013-07-13T17:06:21.047 回答