HashSet内存泄露

举个栗子

public class Person {
    String name;
    int age;

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}

很简单的Person类,为了使用HashSet,Person类最好复写hashcodeequals方法

测试

import java.util.HashSet;
import java.util.Set;

public class PersonTest {

    public static void main(String[] args) {
        Set<Person> ps = new HashSet<>();
        Person p = new Person("joshua", 25);

        ps.add(p);
        p.name = "aw";
        ps.remove(p);
        System.out.println(ps.size());
    }
}

程序输出结果为:1

分析

Person的hash值由name和age共同计算得出

  1. 当p插入ps中时,根据name与age计算hash值进行插入
  2. 插入后改变了对象p的name值
  3. remove(p)时根据新的name与age计算hash值进行查找(此hash值不同于原hash值)
  4. 由于hash值不同,在HashSet对应的位置无法查找到该对象,因此无法删除
  5. 由于该对象的引用还保存在ps中,所以无法回收(产生内存泄露)

结论

  1. 对象加入Hash表中之后不要更改用于计算Hash值的属性
  2. 会发生改变的属性不要用于计算Hash值

PS:若对HashSet的实现有疑问,可以提出来哦
HashSet的实现原理在这里

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 9,148评论 0 11
  • 20- 枚举,枚举原始值,枚举相关值,switch提取枚举关联值 Swift枚举: Swift中的枚举比OC中的枚...
    iOS_恒仔阅读 6,859评论 1 6
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 32,004评论 18 399
  • 对已经验证成功的创新,大多数人会觉得那创新是理所当然的正确,而对于未经验证的创新,大多数人会各种怀疑。有的时候这怀...
    真阿当阅读 3,928评论 0 3
  • 共读:《午饭》和《棕色的熊,棕色的熊,你在看什么》和《妈妈的吻》,最喜欢的还是妈妈的吻,每翻一页都要吻我 反思:晚...
    小窗幽记_hj阅读 1,046评论 0 0