A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© xingzjx 中级黑马   /  2015-3-17 17:47  /  734 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 xingzjx 于 2015-3-17 17:53 编辑

1、hashCode概念
hashCode是根据对象的地址计算出来的int类型的值,在jdk里面public native int hashCode();返回的是hashCode值。
2、作用
hashCode是为了提高查找的效率,在哈希算法中才起作用。如Map的查找,Set的去重。
3、哈希查找原理
   如果要确定一个集合中是否包含某个元素,有一种思路,就是遍历这个集合里面的元素和要要查找的那个元素比较,如果两个元素相同查找成功。这种思路的问题是,假如集合元素很多如10000个,那么一个一个遍历效率自然很低,于是有一种办法,就是把这些元素分成若干的区域,每个元素(对象)都计算出一个hashCode然后将哈希码分组,每组对应某个存储区域,通过对象的哈希码就可以确定对象在哪个区域,我们只需要在那个区域进行查找就行,不必遍历集合中全部元素。
哈希算法的原理图如下:

4、hashCode特点
(1)只有数据集合采用了哈希算法的时候,hashCode才起作用,如Set和Map对象及其子类,如果是ArrayList,hashCode就没意义了。
(2)两个对象相等,hashCode一定相等,反之,未必。
5、内存泄漏
先看看下面这个程序,在这个程序里面重写了equals和hashCode方法:
  1. public class ObjectDemo {

  2.         public static void main(String[] args) {
  3.                 Point p1 = new Point(2, 1);
  4.                 Point p2 = new Point(2, 1);
  5.                 Point p3 = new Point(3, 4);
  6.                
  7.                 Collection<Point> c = new HashSet<Point>();
  8.                 c.add(p1);
  9.                 c.add(p2);
  10.                 c.add(p3);
  11.                 c.add(p1);
  12.                 p1.setX(7);
  13.                 c.remove(p1);
  14.                 System.out.println(c.size());               
  15. }

  16. class Point {
  17.         private int x = 0;
  18.         private int y = 0;

  19.         public Point(int x, int y) {
  20.                 this.x = x;
  21.                 this.y = y;
  22.         }

  23.         public int getX() {
  24.                 return x;
  25.         }

  26.         public void setX(int x) {
  27.                 this.x = x;
  28.         }

  29.         public int getY() {
  30.                 return y;
  31.         }

  32.         public void setY(int y) {
  33.                 this.y = y;
  34.         }

  35.         @Override
  36.         public int hashCode() {
  37.                 final int prime = 31;
  38.                 int result = 1;
  39.                 result = prime * result + x;
  40.                 result = prime * result + y;
  41.                 return result;
  42.         }

  43.         @Override
  44.         public boolean equals(Object obj) {
  45.                 if (this == obj)
  46.                         return true;
  47.                 if (obj == null)
  48.                         return false;
  49.                 if (getClass() != obj.getClass())
  50.                         return false;
  51.                 Point other = (Point) obj;
  52.                 if (x != other.x)
  53.                         return false;
  54.                 if (y != other.y)
  55.                         return false;
  56.                 return true;
  57.         }
  58.        
  59. }
复制代码


上面的程序把语句p1.setX(7)注释掉后,打印结果是1,而加上这条语句后执行结果是2。打印结果是1执行正常,但是为什么出现打印结果是2呢,原因是执行p1.setX(7)之后
hashCode发生了改变,所以p1和p2指向的对象被分配到不同的存储区域,而执行语句c.remove(p1)时,仍然去原来的区域移除对象,那么对象自然移除不了,所以对象一直不被释放(对象p1还被引用着),出现了内存泄露的问题。
6、浅谈ArrayList和HashSet区别
(1)ArrayList是一个有序的集合,里面允许存在重复的元素
(2)HashSet是无序的集合,不允许有重复的元素存在,它是通过哈希算法进行去重和查找的
(3)列表实现的contains查找算法是遍历循环查找,而集里面的查找是基于哈希查找算法,所以当数据元素 很大时候,列表的查找方式很慢,而集的查找方式依然很快。

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马