26 ArrayList_HashSet的比较及Hashcode分析

 

只有类的实例对象要被采用哈希算法进行存储和检索时,这个类才需要按要求覆盖hashCode方法。即使程序可能暂时不会用到当前类的hashCode方法,但是为他提供一个hashCode方法也不会有什么不好,没准以后什么时候有用到这个方法了,所以,通常要求hashCode方法和equals方法一并被同时覆盖。

 

//HashSet比较时hashCode方法和equals方法都用了

HashSet:采用哈希算法的集合。实现了Collection接口,只能存入不同HashCode对象,即只存入不同的对象,如果希望存入具有相同内容的两个对象,则需覆盖对象的HashCode equals方法。

 

提示

1)通常情况,自己编程时要做到:一个类的两个实例对象用equals方法比较的结果相等时,他们的哈希吗也必须相等,但反之则不成立,即equals方法比较的结果不相等的对象可以有相等的哈希吗或者说哈希吗相等的两个对象的equals方法的比较的结果可以不相等。因为默认的equals方法比较的是hashcoad值。例如,字符串”BB””Aa”hashCode的结果相等,但equals的结果不相等。

2当一个对象被存储进HashSet集合中以后,就不能修改这个歌对象中的那些参与计算哈希值的字段,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前的引用作为参数区HsahSet集合中检索对象,也将返回找不到对象的结果,这也是导致无法从HashSet集合中单独删除当前对象,从而造成内存泄露。

例子:

package cn.zyj26.review;
 
public class ReflectPoint {
 
   private int x;
   public int y;
  
   public ReflectPoint(int x, int y) {
      super();
      this.x = x;
      this.y = y;
   }
   public int getX() {
      return x;
   }
 
 
   public void setX(int x) {
      this.x = x;
   }
 
 
   public int getY() {
      return y;
   }
 
 
   public void setY(int y) {
      this.y = y;
   }
   @Override
   public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + x;
      result = prime * result + y;
      return result;
   }
   @Override
   public boolean equals(Object obj) {
      if (this == obj)
         return true;
      if (obj == null)
         return false;
      if (getClass() != obj.getClass())
         return false;
      ReflectPoint other = (ReflectPoint) obj;
      if (x != other.x)
         return false;
      if (y != other.y)
         return false;
      return true;
   }
  
}
 

 

 

 

package cn.zyj26.review;
 
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
 
 
public class ReflectTest2 {
 
   public static void main(String[] args) throws Exception{
      Collection<ReflectPoint> collections=new ArrayList<ReflectPoint>();
      ReflectPoint pt1 = new ReflectPoint(1,1);
      ReflectPoint pt2 = new ReflectPoint(2,2);
      ReflectPoint pt3 = new ReflectPoint(1,1);//默认的equals方法比较的是hashcoad值,所以pt3与pt1不相等,要相等必须重写equals方法
      collections.add(pt1);
      collections.add(pt2);
      collections.add(pt3);
      collections.add(pt1);
      System.out.println(collections.size());//4
      Collection<ReflectPoint> collectionsH=new HashSet<ReflectPoint>();
      collectionsH.add(pt1);
      collectionsH.add(pt2);
      collectionsH.add(pt3);
      collectionsH.add(pt1);//3,重写equals可以得到结果2
      System.out.println(collectionsH.contains(pt1));//true
      pt1.y=22;//导致哈希值改变了!!这样也无法删除了,即collectionsH.remove(pt1);无效了
      System.out.println(collectionsH.contains(pt1));//false
      System.out.println(collectionsH.size());
   }
}

 

 

 

Ps

解释equals()hashcode()== http://justsee.iteye.com/blog/1317565

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值