Java中的HashCode(2)之Hashset造成的内存泄露

所谓内存泄露就是一个对象占用的一块内存,当这个对象不在被使用时,该内存还没有被收回。

 

例子

package cn.xy.test;

public class Point2
{
 private int x;
 private int y;

 public Point2(int x, int y)
 {
  super();
  this.x = x;
  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;
  Point2 other = (Point2) obj;
  if (x != other.x) return false;
  if (y != other.y) return false;
  return true;
 }

 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;
 }

}

public class HashSetAndHashCode2
{
 public static void main(String[] args)
 {
  HashSet<Point2> hs2 = new HashSet<Point2>();
  Point2 p21 = new Point2(3, 3);
  Point2 p22 = new Point2(3, 5);
  hs2.add(p21);
  hs2.add(p22);
  p22.setY(7);
  hs2.remove(p22);
  System.out.println(hs2.size());
 }
}

很多人认为打印出的结果是1。结果是2。为什么呢?当一个对象被存储在Hashset中后,如果修改参与计算hashcode有关的字段,那么修改后的hashcode的值就与一开始存储进来的hashcode的值不同了,这样contains无法通过hashcode找到该元素,所以无法删除。这就告诉我们,当一个对象被存储在Hashset中后,不要修改与计算hashcode有关的字段。

 

 

时间: 2024-10-24 10:40:06

Java中的HashCode(2)之Hashset造成的内存泄露的相关文章

浅谈Java中的hashcode方法

哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个方法的声明可知,该方法返回一个int类型的数值,并且是本地方法,因此在Object类中并没有给出具体的实现. 为何Object类需要这样一个方法?它有什么作用呢?今天我们就来具体探讨一下hashCode方法. 一.hashCode方法的作用 对于包含容器类型的程序设计语言来说,基本上都会涉及到has

浅谈Java中的hashcode方法(推荐)_java

哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个方法的声明可知,该方法返回一个int类型的数值,并且是本地方法,因此在Object类中并没有给出具体的实现. 为何Object类需要这样一个方法?它有什么作用呢?今天我们就来具体探讨一下hashCode方法. 一.hashCode方法的作用 对于包含容器类型的程序设计语言来说,基本上都会涉及到has

Java中的HashCode(1)之hash算法基本原理

  一.为什么要有Hash算法 Java中的集合有两类,一类是List,一类是Set.List内的元素是有序的,元素可以重复.Set元素无序,但元素不可重复.要想保证元素不重复,两个元素是否重复应该依据什么来判断呢?用Object.equals方法.但若每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了.也就是说若集合中已有1000个元素,那么第1001个元素加入集合时,它就要调用1000次equals方法.这显然会大大降低效率.于是Java采用了哈希表的原理.

java中的hashCode方法小例子_java

在java中,有一个这样的规定,就是两个相同的对象(即equals运算为true),它们的hash code也必须相同.在Object类中有一个hashCode方法,可以调用它来查看对象的hash code.下面举例说明. 复制代码 代码如下: package test; public class Test {  public static void main(String args[]){  String str1 = "aaa";  String str2 = str1;  Str

java中一个汉字和一个字母所占内存字节比较以及后台验证的减半处理

  基本概念 我们一般理解java中 一个字符char占2个字节byte 一个汉字占2个字节byte 一个字母占1个字节byte   其他情况 对于汉字来说,采用gbk编码占两字节,采用utf8编码占三个字节.   String的length()方法 String s1 = "aa"; String s2 = "a好"; s1.length() s2.length() 答案都是2,因为该方法是返回字符的个数,并不是内存中的字节数.   数据库应用 java的编码不会

Java中HashMap和Hashtable及HashSet的区别_java

Hashtable类   Hashtable继承Map接口,实现一个key-value映射的哈希表.任何非空(non-null)的对象都可作为key或者value.   添加数据使用put(key,value),取出数据使用get(key),这两个基本操作的时间开销为常数.   Hashtable通过initial   capacity和load   factor两个参数调整性能.通常缺省的load   factor   0.75较好地实现了时间和空间的均衡.增大load   factor可以节

浅析Java中Map与HashMap,Hashtable,HashSet的区别_java

HashTable和HashMap区别 第一,继承的父类不同.Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类.但二者都实现了Map接口. 复制代码 代码如下: public class Hashtable<K,V>extends Dictionary<K,V>implements Map<K,V>, Cloneable, Serializable public class HashMap<K,V>extends

HashMap在Android和Java中的不同实现

起因 今天在项目中遇到一个很"奇葩"的问题.情况大致是这样的:Android终端和服务器(Spring),完全相同的字符串键值对放入HashMap中竟然顺序不一样,这直接导致了服务器和Android终端用HmacSHA256算法加密出的摘要也不一样,服务器也就无法进行正确的数据验证. 然后带着郁闷的心情给程序加断点进行原因寻找,发现原来是HashMap的中服务器和终端双方对于同样的key存放顺序竟然不一样! 在HashCode产生冲突的情况下,不同的key在HashMap中存入的位置应

浅析Java中的GC垃圾回收器的意义及与GC的交互_java

对象是使用new创建的,但是并没有与之相对应的delete操作来回收对象占用的内存.当我们完成对某个对象的使用时,只需停止对该对象的引用:将我们的引用改变为指向其他对象或指向null;或者从方法中返回,使得该方法的局部变量不复存在,从而使得对这些局部变量的引用变为不指向任何对象.不再被引用的对象被称为垃圾(garbage),查找并回收这些对象的过程叫做垃圾回收(garbage collection) o Java虚拟机利用垃圾回收来保证被引用的对象将会在内存中保留,同时会释放在执行代码中通过任何