如何确保哈希码偶然不等于同一类型的另一个对象

时间:2013-12-26 00:52:07

标签: java hashcode

我正在试验复制构造函数来克隆车辆对象。我只是为了演示而重写了名为Vehicle的类的toString()方法。但克隆必须是独特的,完全独立。

如果我创建了数千个Vehicle对象的克隆,并且使用equals()方法相互检查时所有克隆都是唯一的,是否可以保证?我的印象是,当我使用equals()方法进行比较时,所创建的每个对象都保证始终具有一个永远不会与另一个相等的新的哈希码。

编辑: 我的问题是,使用默认的equals()方法比较我的100000个克隆,确保每个克隆实际上是唯一的,而equals()将始终返回false ???

public class App {

    public List<Vehicle> buildCar(String type, int hp)
    {
        List<Vehicle> vs = new ArrayList<Vehicle>();
        Vehicle vObject = new Vehicle();
        vObject.setHorsePower(hp);
        vObject.setType(type);

        Vehicle newV = new Vehicle(vObject);
        vs.add(newV);
        vs.add(vObject);
        return vs;
    }   

    public static void main(String args[]){
        App ap = new App();
        List<Vehicle> vehicles = new ArrayList<Vehicle>();

        vehicles.addAll(ap.buildCar("car",100));

        Vehicle v1 = vehicles.get(0);
        Vehicle v2 = vehicles.get(1);

        System.out.println(v1.equals(v2)); // prints false.
                //System.out.println(v2.hashCode());

    }
}

3 个答案:

答案 0 :(得分:1)

那是错的。 hashCode()函数返回int。因此,在创建2^32 + 1个对象时,至少会有一个哈希码出现两次。

默认情况下(如果不覆盖hashCode()函数),对象将在内存中将其地址作为哈希码。这就是为什么你会得到它独特的印象。您正在创建没有足够的对象来分配足够的内存来获得两个相同的哈希码。


  

如何确保通过克隆生成的对象实际上是完全独立且独一无二的?

独立性和独特性是不同的标准。

独立意味着对象及其克隆不共享状态。因此,如果(例如)您的Vehicle对象具有可变组件,则需要确保您的clone方法也克隆组件。

唯一性需要更多信息。具体来说,这取决于您使用什么作为唯一性的“测试”。

  • 如果您使用==作为唯一性测试,那么创建新对象的clone的任何实现都将满足要求。 (clone的正常期望是创建一个新对象...)

  • 如果您使用equals作为唯一性测试,那么这取决于您如何定义equals方法。 equals的默认实施使用==。如果您基于对象字段覆盖equals以进行测试,那么如果您希望克隆是唯一的(根据equals),您需要某种标识符字段作为对象标识< / em> ...并安排您的clone方法为每个克隆提供一个新的标识符值。 (这意味着仅仅委托给Object.clone()是不够的。)


  

我的问题是,是否会使用默认的equals()方法来比较我的100000个克隆,确保每个克隆实际上都是唯一的,而equals()总是会返回false?

是......对于clone()的任何合理实施。

Java equals(Object)的默认实现与Java ==执行相同的测试,如果两个操作数是相同的对象引用,那么它只会给你true

答案 1 :(得分:1)

equals方法将始终区分相等(无论意味着什么)和不等于100%准确度。比较哈希码只能保证意味着&#34;不等于&#34;如果哈希码不匹配 - 相等的哈希码并不意味着&#34;等于&#34;将是真的。

哈希码的一个牢不可破的规则是,如果两个对象为&#34;等于&#34;则返回true。那么他们的哈希码必须匹配。

答案 2 :(得分:0)

如果您使用任何正确的clone实现,则结果是与原始对象不同的对象(即original.clone() != original)。

Object的equals实现检查对象是否相同(返回值与==相同),即只要clone()是克隆,它就不会返回true正确实施。 基本上你可以把o.equals(o2)想象成一个检查,如果2个对象变量o和o2引用占用相同的内存。 (仍然在谈论非重写等于实现)

因此,如果用等号检查,克隆和原始将成对不同。