关于hashcode的那些有趣的事情

hashcode的作用是让基于散列的集合正常的运行,这些散列的集合有:HashSet、HashMap以及HashTable。
举个例子:当我们需要添加一个元素的时候a进Set的时候,我们会计算出a的hashcode,然后求余,得到这个哈希值应该在哪个桶里,最后在桶里边找有没有散列值跟a这个元素的散列值相同的,没有的话,最直接添加有的话,再用equals方法判断,添加的值。

有趣的例子1:可变数据类型的操作改变,导致哈希值的改变

    List<String> list = new ArrayList<>();
    list.add("a");
    Set<List<String>> set = new HashSet<>();
    set.add(list);//把list添加到set里
    System.out.println(set.contains(list));//true
    list.add("b");//对list进行操作
    list.add("c");
    System.out.println(set.contains(list));//false,为什么不是true

简述:
??

有趣的例子2 重写equals方法要重写hashcode
比较有两种方式行为比较和观察比较,为了满足我们需要的比较,我们改写equals方法,下面是代码

 public static void main(String args[]){
    Set<Student> s = new HashSet<>();
    s.add(new Student("a","b"));
    System.out.println("添加完毕");
    System.out.println(s.contains(new Student("a","b")));
  }
public class Student{
  public final String start;
  public final String stop;
  public Student(String start,String stop) {
    this.start = start;
    this.stop = stop;
  }  
  @Override
  public boolean equals(Object s) {
    if(!(s instanceof Student)) {
      return false;
    } 
    Student ss = (Student) s;
    System.out.println("equals方法被调用啦");
    return start.equals(ss.start) && stop.equals(ss.stop);
  }
}

但是结果却是false,这是因为前边说过,判断是否包含,需要判断hashcode是否相等,再使用equals,这里我们虽然重写了equals方法,但是由于是两个new,他们的地址肯定不同(即hashcode不相同),运行可以得到验证

所以还要再重写hashcode,在Student里边添加下面代码

@Override 
public int hashCode() {
    int result = 17;
    result = 31*result + start.hashCode();
    result = 31*result + stop.hashCode();
    System.out.println("hashcode方法被调用啦"+" "+"hashcode: "+result);
    return result; 
}

这里还有一个很有意思的验证,验证了set使用contains判断是否包含的步骤是怎么样的,再次运行,打印出来的结果是:

hashcode方法被调用啦 hashcode: 19442
添加完毕
hashcode方法被调用啦 hashcode: 19442
equals方法被调用啦
true

说明每次new都回去查看这个new的散列值,当处理contains的时候,就拿第二个new的值,去跟set所有的散列值比,如果相同的话,就继续调用equals

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值