hashCode()方法以及集合中Set的一些总结

一、前言本篇文章没有什么主题,就是一些零散点的总结。周末没事看了几道蚂蚁金服的面试题,其中有好几道都是特别简单的,基础性的题目,就是我们平时用到的,但是发现要是完全说出来还是有一些不清楚的地方,所以小小的总结一下。二、hashCode()方法理解提到hashCode()必然会涉及equals()方法,二者是紧密相连的,其实面试中被问到这方面往往是考察集合存储对象判断相等的问题。比如有如下...
摘要由CSDN通过智能技术生成
一、前言

本篇文章没有什么主题,就是一些零散点的总结。
周末没事看了几道蚂蚁金服的面试题,其中有好几道都是特别简单的,基础性的题目,就是我们平时用到的,但是发现要是完全说出来还是有一些不清楚的地方,所以小小的总结一下。

二、hashCode()方法理解

提到hashCode()必然会涉及equals()方法,二者是紧密相连的,其实面试中被问到这方面往往是考察集合存储对象判断相等的问题。

比如有如下Person类:

public class Person {

    private int age;
    private String name;

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        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);
    }
}

很简单吧,我这里只重写了equals方法,如果我们以Person类对象作为key存储在HashMap中,如下:

HashMap map = new HashMap();
map.put(new Person(45,"lisi"),"123");
System.out.println(map.get(new Person(45,"lisi")));

试想一下能正常取出"lisi"值吗?对HashMap源码看过的同学肯定知道取不出来,打印如下:

null

HashMap在取数据的时候会检查对应的key是否已经存储过,这个比较简单来说就是比较key的hashcode()值以及equals()是否相等的比较,只有二者均相同才会认为已经存储过,对于上述Person类我们只重写了equals方法,对于hashcode()方法默认调用的是Object类中的hashcode()方法:

    public int hashCode() {
        return identityHashCode(this);
    }

不同对象会生成不同的hash值,所以严格来说hashcode()与equals()方法我们最好同时重写,否则与集合类结合使用的时候会产生问题,改造Person类添加如下hashcode()方法:

    @Override
    public int hashCode() {
        return Objects.hash(age, name);//根据类中属性生成对应hash值
    }

这样就可以正常获取对应值了。

HashMap中比较元素是否相同是根据Key的hashcode值以及equals来判断是否相同的。

三、Set集合常用类相关问题

Set集合常用与存储不重复的数据,也就是集合中数据都不相等,但是不同具体实现类判断是否相等是不一样,这也是面试中会问到的问题,比如TreeSet是怎么判断元素是否相同的?HashSet是怎么判断的?

其实稍微看一下源码就明白了,Set具体实现类都是依靠对应map来实现的:

  • HashSet底层依靠HashMap来实现
  • TreeSet底层依靠TreeMap来实现
  • LinkedHashSet底层依靠LinkedHashMap来实现
HashSet

看一下HashSet源码吧:

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
    static final long serialVersionUID = -5024744406713321676L;

    private transient HashMap<E,Object> map;

    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();

    public HashSet() {
        map = new HashMap<>();
    }

    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }

    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }

    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }

    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值