无法理解输出

时间:2016-05-02 10:43:04

标签: java

在下面的代码中,根据多次运行后为对象生成的哈希码值,会产生不同的三个输出

Output1
collection.A@1
0
collection.A@0
0
true


Output2
collection.A@1
0
collection.A@0
1
true

Output3
collection.A@1
1
collection.A@1
1
true

我无法理解即将发生的三种不同输出, 对于例如Output3,如果哈希码与它们相同并且equals返回true,则为什么添加两个对象 Simliarly我无法理解Output1& 2

 public class A {

    @Override
    public int hashCode() {
        long l=Math.round(Math.random());
        return (int)l;

    }

    @Override
    public boolean equals(Object arg0) {
        return true;
    }


    public static void main(String args[]){

        Set<A> h=new HashSet<A>();
        for(int i=0;i<100;i++)
            h.add(new A());

        for (A a : h) {
            System.out.println(a);
            System.out.println(a.hashCode());
        }
        System.out.println(h.contains(new A()));
    }
}

4 个答案:

答案 0 :(得分:3)

基本上,您的代码违反了hashCode()的合同。

实施hashCode的规则之一是必须始终如此:

obj.hashCode() == obj.hashCode()

但在你的情况下,这不是。每次调用hashCode时,结果都可能与前一次调用的结果不同。这是因为Math.random()每次都返回不同的值。

为什么只有两个对象被添加到集合中?

因为只有具有不同哈希码的对象才能添加到HashSet。如果添加了哈希码为1的对象,则无法添加哈希码为1的另一个对象。

由于你的hashCode方法只能返回两个不同的整数 - 1和0,最多可以添加2个对象。

在输出3中,为什么我在集合中看到两个具有相同哈希码的对象?

collection.A@1
1
collection.A@1
1
true

这是因为您的hashCode方法每次调用时都会返回不同的值。可能当两个对象添加到集合中时,它们的hashCode方法返回不同的值。但是当你打电话给它时,它们会变成相同的值。

任何事情都可能发生,你知道!

P.S。我希望这不是生产代码......

答案 1 :(得分:1)

因为您的Math.round(Math.random());始终返回0或1.如果您需要更大范围的随机值,它应该像Math.round(Math.random()*10000); 您必须在A类中覆盖toString()方法。

将以下方法添加到类A,或者可以将其修改为您自己的方法。

@Override
public String toString() {
    return "Class A";

}

同时更改hashCode()方法,然后尝试。

@Override
public int hashCode() {
    long l=Math.round(Math.random()*10000);
    return (int)l;

}

答案 2 :(得分:1)

  

对于例如Output3,如果哈希码相同,为什么要添加两个对象

由于每次检查时哈希码都可能不同,因此可能会出现结果的异常。

如果所有100个对象在插入时返回相同的哈希码(成对),则该集合将只包含一个对象。这个概率是 @Test(parameters = { "param1"}) public void testExmaple(String param1){ //do something with param1 } 或几乎为0。

打印结果时,会生成新的哈希码。您打印的值与插入期间比较中使用的值无关。

尝试记住字段中生成的哈希码值,并让每个对象每次返回相同的值,每次结果都是相同的。

答案 3 :(得分:0)

Math.random()

的bcoz
  

Math.random()返回大于或等于0.0且小于1.0的伪随机double