您的位置:首页 > 编程语言 > Java开发

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

2017-02-05 23:30 489 查看
我们经常使用的集合如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方法如果哈希值不同,就根本不用在比较了.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐