HashMap put不会为一维超过128的点添加值,也不会出现溢出错误

时间:2013-07-13 17:02:27

标签: java hashmap

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

当HashMap.put(Point,Double)用于坐标值> gt = 128的Point时,HashMap似乎没有做任何事情。没有抛出错误,但是尝试从HashMap访问Points会导致密钥没有被发现。我在INTEGER.MAX_VALUE下很好,并且有足够的内存。

这是我的Point类:

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

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

1 个答案:

答案 0 :(得分: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   列表具有相同的大小,以及所有相应的元素对   两个列表相等

此外,您不应在Key可变对象中使用hash valued mapAre mutable hashmap key dangerous?

  

如果对象的hashCode()值可以根据其状态改变,那么我们   在基于哈希的键中使用此类对象时必须小心   集合,以确保我们不允许他们的状态改变时   它们被用作哈希键。所有基于散列的集合都假定   对象的哈希值在使用时不会改变   集合中的关键。如果密钥的哈希码在其中发生变化   是一个集合,一些不可预测和混乱的后果   可以跟着。