HashSet底层理解面试题

╄→尐↘猪︶ㄣ 提交于 2019-11-27 12:12:27
import org.junit.Test;

import java.util.HashSet;

/**
 * @author xianyu
 * @time 2019-08-16-9:40
 */
public class HashSetTest {
    @Test
    public void test(){
        //*************1******************
        HashSet set = new HashSet();
        Person p1 = new Person("AA",23);
        Person p2 = new Person("BB",21);
        set.add(p1);
        set.add(p2);
        System.out.println(set);   //[Person{name='BB', age=21}, Person{name='AA', age=23}]
        
        //*************2******************
        p1.name = "CC";
        set.remove(p1);
        System.out.println(set);   //[Person{name='BB', age=21}, Person{name='CC', age=23}]
        
        ///*************3******************
        set.add(new Person("CC",23));
        System.out.println(set);    //[Person{name='BB', age=21}, Person{name='CC', age=23}, Person{name='CC', age=23}]
        
        //*************4******************
        set.add(new Person("AA",23));
        System.out.println(set);   //[Person{name='BB', age=21}, Person{name='CC', age=23}, Person{name='AA', age=23}, Person{name='CC', age=23}]
        
    }

}

结果:

[Person{name='BB', age=21}, Person{name='AA', age=23}]
[Person{name='BB', age=21}, Person{name='CC', age=23}]
[Person{name='BB', age=21}, Person{name='CC', age=23}, Person{name='CC', age=23}]
[Person{name='BB', age=21}, Person{name='CC', age=23}, Person{name='AA', age=23}, Person{name='CC', age=23}]

注意:Person类重写了toString(), equals() 和hashcode() 方法

关于这段程序的理解:
首先注释1部分

        //*************1******************
        HashSet set = new HashSet();
        Person p1 = new Person("AA",23);
        Person p2 = new Person("BB",21);
        set.add(p1);
        set.add(p2);
        System.out.println(set);   //[Person{name='BB', age=21}, Person{name='AA', age=23}]
     
     这段代码很简单,建一个HashSet集合,集合和存放两个不同的Person对象,故两个集合的hashcode值不同,所以底层在用数组存放的时候,不管使用什么映射函数都有很大概率被映射到两个不同的位置下,记为 x, y

注释2部分

     //*************2******************
        p1.name = "CC";
        set.remove(p1);
        System.out.println(set);   //[Person{name='BB', age=21}, Person{name='CC', age=23}]
  这部分,首先把底层数组存放的p1位置的name属性改为 cc,注意虽然name属性改为了cc,但该位置x仍然是由原先的(AA,23)映射来的。然后set集合做了删除remove操作,这里remove的是(cc,23),这里通过hashcode值和映射函数,找到(cc,23)所映射的位置z, 这个位置此时没有元素,所以remove也就删除的是空的元素,也就等于没有set集合没有改变


注释3部分

        ///*************3******************
        set.add(new Person("CC",23));
        System.out.println(set);    //[Person{name='BB', age=21}, Person{name='CC', age=23}, Person{name='CC', age=23}]
 这段代码就是在刚才那个z位置存放元素(cc,23)

注释4部分

        //*************4******************
        set.add(new Person("AA",23));
        System.out.println(set);   //[Person{name='BB', age=21}, Person{name='CC', age=23}, Person{name='AA', age=23}, Person{name='CC', age=23}]
 这段代码是在(AA,23)所映射的位置x处存放(AA,23)对象,由于原先在该位置存放的元素已由(AA,23)改为(cc,23),所有现在再存放(AA,23)时就不会有冲突,所有可以正常存进去
 
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!