首页 > 学院 > 开发设计 > 正文

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

2019-11-14 08:50:21
字体:
来源:转载
供稿:网友

我们经常使用的集合如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方法如果哈希值不同,就根本不用在比较了.


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表