Java中 判断集合中的元素相等的依据 详细解析
2017-02-05 23:30
489 查看
我们经常使用的集合如ArrayList,LinkedList,Vector,
**你在调用contains()方法的时候, 或者是你在根据对象移除元素 remove(Object o) 你知道他们是如何判断集合中的元素是否
是相等的吗**?
接下来我们跟着源码去详细探究一下
数据数据结构不同判断的依据就不同,我们先来看一下List类的判断依据.
先简单的了解一下
List类 : 有序,可以有重复元素。
ArrayList 底层是一个对象数组
LinkedList 属于链式数据结构,底层用的是一个Node类的节点,包括指针域和数据域.
private static class Node {
E item;
Node next;
Node prev;
ArrayList LinkedList他们都是线程不同步的 Vector非常类似ArrayList,但是Vector是同步的。, ArrayList LinkedList多线程访问会抛出 ConcurrentModificationException。如果想使他们线程同步的可以使用 Collections.synchronizedList 方法将该集合“包装”起来
回归正题
我们想知道他们如何判断集合元素是否相等,我们应该想到的是contains(Object o)方法,接下来我们看一下contains(Object o)方法
他的方法内部调用了indexOf(o)这个方法,我们继续追踪看一下indexOf(o)方法
看到这里我们应该能明白了 先判断要查找的元素是否为空,不为空的话就调用equals方法.由此我们得到一个结论
List类中判断元素是否相等依赖的是equals方法.
set类 : 无序,不允许重复
HashSet :
此实现不是同步的
我们知道HashSet它不允许出现重复元素,他是如何保证元素唯一的呢,我们应该首先想到的是看他的add()方法
如下
这里出现了一个map我们找找看看他是什么
我们在上面看到了他的定义
现在我们知道了HashSet的内部其实是一个HashMap来维护的,众所周知HashMap的键是不允许有相同的,不用说HashMap的键就是HashSet的值,接下来我们只需要知道HashMap的键是如何保证唯一的就行了
我们就要追踪HashMap的添加元素方法 put(K key, V value)
虽然有点麻烦我们只需要仔细看看 一定可以看明白 抓住最重要的一句
现在我们也知道了HashSet 和HaspMap 保证元素唯一的办法是 先比较两个元素的哈希值,如果哈希值相等,在比较元素的地址是否相同,或者调用两个元素的equals方法如果哈希值不同,就根本不用在比较了.
**你在调用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方法如果哈希值不同,就根本不用在比较了.
相关文章推荐
- Java 集合系列07之 Stack详细介绍(源码解析)和使用示例
- Java 集合系列11之 Hashtable详细介绍(源码解析)和使用示例
- Java 集合系列17之 TreeSet详细介绍(源码解析)和使用示例
- Java 集合系列06之 Vector详细介绍(源码解析)和使用示例
- Java 集合系列11之 Hashtable详细介绍(源码解析)和使用示例
- Java 集合系列13之 WeakHashMap详细介绍(源码解析)和使用示例
- Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例
- java怎么判断两个Set 里的对象的值是否相同【两个set中的值是否相等】、java treeset和hashset如何判断元素是否相同【即对象是否完全相同;利用一个set去除重复元素】
- Java 集合系列07之 Stack详细介绍(源码解析)和使用示例
- Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例
- Java 集合系列17之 TreeSet详细介绍(源码解析)和使用示例
- Java 集合系列 10 Hashtable详细介绍(源码解析)和使用示例
- Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例
- 【转】Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
- Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
- Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例
- Java 集合系列 06 Stack详细介绍(源码解析)和使用示例
- Java 集合系列 09 HashMap详细介绍(源码解析)和使用示例
- Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
- 【转】Java 集合系列16之 HashSet详细介绍(源码解析)和使用示例--不错