equals()和hashCode()

本文详细解析了Java中String、ArrayList、LinkedList、HashSet、TreeSet及HashMap的equals和hashCode方法实现,揭示了这些方法在不同集合类中的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

equals()和hashCode()

String中的equals()和hashCode()

equals():

1.首先比较两个对象的引用,若引用相同,则返回true
2.判断anObject是否是String类型,如果是,将两个字符串转为字节数组逐字节进行比对,始终相同返回true,有一个字节不同返回false
3.返回false

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

hashCode():

如果hash值等于0并且字符数组长度大于0,计算hash值。hash值计算方法为逐字符数组计算字符值加hash值的31倍

public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

ArrayList和LinkedList中的equals()和hashCode()

ArrayList和LinkedList继承自java.util.AbstractList,ArrayList和LinkedList中并没有实现equals()和hashCode(),而是继承了父类的实现方法

equals()

1.判断两个集合的引用是否相同,如果相同则返回true
2.判断o是否是一个List集合,如果不是返回false
3.生成两个对象的迭代器,逐个比较对象:如果o1等于空判断o2是否为空,如果不是,返回false;如果o1不为空且o1不等于o2,返回false
4.如果两个集合的对象长度不等,返回false

public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof List))
            return false;

        ListIterator<E> e1 = listIterator();
        ListIterator<?> e2 = ((List<?>) o).listIterator();
        while (e1.hasNext() && e2.hasNext()) {
            E o1 = e1.next();
            Object o2 = e2.next();
            if (!(o1==null ? o2==null : o1.equals(o2)))
                return false;
        }
        return !(e1.hasNext() || e2.hasNext());
    }

hashCode()

1.默认hash值为1
2.逐对象计算hash值:hash值等于原来的hash的31倍加此次对象的hash值,此次对象为空时该hash值为0

public int hashCode() {
        int hashCode = 1;
        for (E e : this)
            hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
        return hashCode;
    }

HashSet和TreeSet中的equals()和hashCode()

HashSet和TreeSet继承自java.util.AbstractSet,HashSet和TreeSet中并没有实现equals()和hashCode(),而是继承了父类的实现方法

equals()

1.如果两个集合的引用相同,则返回true
2.如果o不是一个Set集合,返回false
3.如果两个集合的长度不同,返回false
4.如果调用方法的集合全部包含o,返回true,否则返回false(这里有必要看一下containsAll())的实现(见下文)

public boolean equals(Object o) {
        if (o == this)
            return true;

        if (!(o instanceof Set))
            return false;
        Collection<?> c = (Collection<?>) o;
        if (c.size() != size())
            return false;
        try {
            return containsAll(c);
        } catch (ClassCastException unused)   {
            return false;
        } catch (NullPointerException unused) {
            return false;
        }
    }
containsAll()

可以看到,containsAll()方法进行比对时,是按照o的长度进行比对的。equals()方法在进行调用containsAll()方法时,已在前面进行过两个集合长度的判断

public boolean containsAll(Collection<?> c) {
        for (Object e : c)
            if (!contains(e))
                return false;
        return true;
    }
public boolean contains(Object o) {
        Iterator<E> it = iterator();
        if (o==null) {
            while (it.hasNext())
                if (it.next()==null)
                    return true;
        } else {
            while (it.hasNext())
                if (o.equals(it.next()))
                    return true;
        }
        return false;
    }

hashCode()

Set集合进行hash计算的方式和List集合有些不同,Set集合进行hash计算只是单纯的逐对象累加每个对象的hash值,hash值默认为0

public int hashCode() {
        int h = 0;
        Iterator<E> i = iterator();
        while (i.hasNext()) {
            E obj = i.next();
            if (obj != null)
                h += obj.hashCode();
        }
        return h;
    }

HashMap中的equals()和hashCode()

HashMap继承自java.util.AbstractMap,其中的equals()和hashCode()方法也是由父类实现

equals()

1.判断两个集合的引用值是否相同,相同返回true
2.判断o是否是一个Map集合,不是返回false
3.判断两个集合长度是否相等,不等返回false
4.将调用equals()方法的集合转为Set集合后遍历,如果该key对应的value为空,则判断o中是否包含该key且key对应的值是否为空;如果该key对应的value值不为空,则判断o中相同key对应的value值是否相等

public boolean equals(Object o) {
        if (o == this)
            return true;

        if (!(o instanceof Map))
            return false;
        Map<?,?> m = (Map<?,?>) o;
        if (m.size() != size())
            return false;

        try {
            Iterator<Entry<K,V>> i = entrySet().iterator();
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                K key = e.getKey();
                V value = e.getValue();
                if (value == null) {
                    if (!(m.get(key)==null && m.containsKey(key)))
                        return false;
                } else {
                    if (!value.equals(m.get(key)))
                        return false;
                }
            }
        } catch (ClassCastException unused) {
            return false;
        } catch (NullPointerException unused) {
            return false;
        }

        return true;
    }

hashCode()

将集合转为Set集合后逐对象计算hash值,hash值初始值为0

public int hashCode() {
        int h = 0;
        Iterator<Entry<K,V>> i = entrySet().iterator();
        while (i.hasNext())
            h += i.next().hashCode();
        return h;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值