HashSet底层理解面试题

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)时就不会有冲突,所有可以正常存进去
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值