Java中 判断集合中的元素相等的依据 详细解析

我们经常使用的集合如ArrayList,LinkedList,Vector,
**你在调用contains()方法的时候, 或者是你在根据对象移除元素 remove(Object o) 你知道他们是如何判断集合中的元素是否
是相等的吗**?
接下来我们跟着源码去详细探究一下
数据数据结构不同判断的依据就不同,我们先来看一下List类的判断依据.

先简单的了解一下
List类 : 有序,可以有重复元素。

ArrayList 底层是一个对象数组
private transient Object[] elementData;
LinkedList 属于链式数据结构,底层用的是一个Node类的节点,包括指针域和数据域.

private static class Node {
E item;
Node next;
Node prev;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

ArrayList LinkedList他们都是线程不同步的 Vector非常类似ArrayList,但是Vector是同步的。, ArrayList LinkedList多线程访问会抛出 ConcurrentModificationException。如果想使他们线程同步的可以使用 Collections.synchronizedList 方法将该集合“包装”起来

回归正题

我们想知道他们如何判断集合元素是否相等,我们应该想到的是contains(Object o)方法,接下来我们看一下contains(Object o)方法

  public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

他的方法内部调用了indexOf(o)这个方法,我们继续追踪看一下indexOf(o)方法

   public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

看到这里我们应该能明白了 先判断要查找的元素是否为空,不为空的话就调用equals方法.由此我们得到一个结论
List类中判断元素是否相等依赖的是equals方法.

set类 : 无序,不允许重复

HashSet :
此实现不是同步的
我们知道HashSet它不允许出现重复元素,他是如何保证元素唯一的呢,我们应该首先想到的是看他的add()方法
如下

public boolean add(E e) {
return map.put(e, PRESENT)==null;
}

这里出现了一个map我们找找看看他是什么

我们在上面看到了他的定义

 private transient HashMap<E,Object> map;

现在我们知道了HashSet的内部其实是一个HashMap来维护的,众所周知HashMap的键是不允许有相同的,不用说HashMap的键就是HashSet的值,接下来我们只需要知道HashMap的键是如何保证唯一的就行了

我们就要追踪HashMap的添加元素方法 put(K key, V value)

public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

虽然有点麻烦我们只需要仔细看看 一定可以看明白 抓住最重要的一句

e.hash == hash && ((k = e.key) == key || key.equals(k))

现在我们也知道了HashSet 和HaspMap 保证元素唯一的办法是 先比较两个元素的哈希值,如果哈希值相等,在比较元素的地址是否相同,或者调用两个元素的equals方法如果哈希值不同,就根本不用在比较了.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值