ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

由一道关于hashSet与hashMap底层实现的面试题

2021-03-21 19:02:49  阅读:134  来源: 互联网

标签:面试题 set hash hashMap hashSet Person p1 1001 name


题目

public class TestPerson {
    public static void main(String[] args) {
        HashSet<Person> set = new HashSet<>();
        Person p1 = new Person(1001, "AAA");
        Person p2 = new Person(1002, "BBB");

        set.add(p1);
        set.add(p2);
        p1.name = "CCC";
        set.remove(p1);
        System.out.println(set);

        set.add(new Person(1001,"CC"));
        System.out.println(set);

        set.add(new Person(1001,"AAA"));
        System.out.println(set);
    }
}

其中Person类重写了hashCode、equals、和toString方法

public class Person {
    int age;
    String name;

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(age, name);
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

问输出结果是多少?


分析

答题前我们首先要知道:
HashSet和HashMap都是由数组+链表+红黑树实现。(JDK1.8后)

HashSet和HashMap存储过程:
1.根据key的hash值计算位置,如果这个位置没有元素,则直接添加。
2.如果这个位置有元素,再比较hash值,如果hash值不同,则形成链表。
3.如果hash值相同,再比较equals方法,如果equals方法为false,则形成链表,如果为true,则认为是重复元素,不再添加。
位置相同,hash值相同,equals为true同时成立才认为是重复元素。

HashSet和HashMap删除过程:
同理要位置相同,hash值相同,equals为true同时成立才认为是重复元素,才能删除。

回到题目
set.add(p1)、set.add(p2): set首先添加p1(1001,“AAA”)、p2(1002,“BBB”)对象后,将p1对象的name值改变了(1001,“CCC”),此时虽然set中p1的属性值为(1001,“CCC”),但其数组位置是按照(1001,“AAA”)计算的。
set.remove(p1): 此时位置是按照更改后的(1000,“CCC”)计算的,与set中存储的p1的位置不同,故认为set中没有与之重复的元素,不删除。
set.add(new Person(1001,“CC”)): 理由同上,此时按照更改后的属性计算的位置与原本计算的位置不同,故认为set中没有与之重复的元素,于是将其添加进数组。
set.add(new Person(1001,“AAA”)): 属性与p1原属性相同,按照此属性计算的位置与p1在数组中存储的位置相同,于是再比较hash值,hash值不同(重写了hashCode函数,属性相同hash相同,属性不同hash不同。当然,不重写hashCode函数两者hash值也不同)。故认为两者不是重复元素,将新对象添加再p1后形成链表。
综上,这道题最后的答案是:在这里插入图片描述

标签:面试题,set,hash,hashMap,hashSet,Person,p1,1001,name
来源: https://blog.csdn.net/shuaiSSSSS123/article/details/115052927

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有