深入解析ADT源码:揭秘Android数据结构的
随着Android系统的不断发展,Android开发者工具包(ADT)也日益完善,其中的数据结构组件在Android应用开发中扮演着至关重要的角色。本文将深入解析ADT源码,带您一窥Android数据结构的核心机制。
一、引言
Android开发过程中,数据结构的选择和运用直接影响到应用的性能和用户体验。ADT提供了丰富的数据结构类,如List、Map、Set等,这些类底层实现依赖于Java集合框架(Collection Framework)。本文将重点分析ADT中几个核心数据结构类的源码,帮助开发者更好地理解和使用这些数据结构。
二、List源码解析
1.ArrayList源码解析
ArrayList是Java集合框架中最常用的List实现之一,它基于动态数组实现。下面是ArrayList的核心方法源码:
`java
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
// ...
private static final int DEFAULT_CAPACITY = 10;
private transient Object[] elementData;
private int size;
public ArrayList() {
this.elementData = DEFAULT_CAPACITY;
}
public ArrayList(int initialCapacity) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
this.elementData = new Object[initialCapacity];
}
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - Integer.MAX_VALUE > 0)
newCapacity = Integer.MAX_VALUE;
elementData = Arrays.copyOf(elementData, newCapacity);
}
public E get(int index) {
rangeCheck(index);
return (E) elementData[index];
}
// ...
}
`
从源码中可以看出,ArrayList通过动态数组实现,当数组容量不足时,会自动扩容。add方法负责将元素添加到数组末尾,如果数组容量不足,则会调用grow方法进行扩容。
2.LinkedList源码解析
LinkedList是基于双向链表实现的List,它具有较好的插入和删除性能。以下是LinkedList的核心方法源码:
`java
public class LinkedList<E> extends AbstractList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable {
// ...
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
}
private transient Node<E> first;
private transient Node<E> last;
private int size;
public LinkedList() {
}
public boolean add(E e) {
linkLast(e);
return true;
}
private void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
}
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
private Node<E> node(int index) {
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1 & ~-1; i > index; i--)
x = x.prev;
return x;
}
}
// ...
}
`
LinkedList通过Node类实现双向链表,add方法将元素添加到链表末尾,get方法通过index查找元素。
三、Map源码解析
1.HashMap源码解析
HashMap是基于哈希表实现的Map,它提供了快速的查找和插入性能。以下是HashMap的核心方法源码:
`java
public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Cloneable, java.io.Serializable {
// ...
static class Node<K, V> implements Map.Entry<K, V> {
final K key;
V value;
Node<K, V> next;
int hash;
Node(int hash, K key, V value, Node<K, V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public final K getKey() {
return key;
}
public final V getValue() {
return value;
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (!(o instanceof Map.Entry)) {
return false;
}
Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
if (key == null) {
if (e.getKey() != null)
return false;
} else if (!key.equals(e.getKey()))
return false;
if (value == null) {
if (e.getValue() != null)
return false;
} else if (!value.equals(e.getValue()))
return false;
return true;
}
public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
}
private static final int DEFAULT_INITIAL_CAPACITY = 16;
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
transient Entry[] table;
transient int size;
int threshold;
final float loadFactor;
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR;
this.threshold = (int)(DEFAULT INITIAL_CAPACITY * DEFAULT LOAD_FACTOR);
table = new Entry[DEFAULT INITIAL_CAPACITY];
}
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
Node<K, V>[] tab; Node<K, V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K, V> e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K, V>)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1)
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping found
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
// ...
}
`
HashMap通过数组存储Node节点,Node节点存储键值对。put方法将键值对添加到HashMap中,如果键已存在,则覆盖原有值。
2.TreeMap源码解析
TreeMap是基于红黑树实现的Map,它按照键的自然顺序或构造时指定的Comparator顺序排序。以下是TreeMap的核心方法源码:
`java
public class TreeMap<K, V> extends AbstractMap<K, V> implements SortedMap<K, V>, Cloneable, java.io.Serializable {
// ...
private static final int DEFAULT_CAPACITY = 16;
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
transient Entry<K, V> root;
transient int size;
private final Comparator<? super K> comparator;
public TreeMap() {
comparator = null;
}
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
public V put(K key, V value) {
Entry<K, V> t = root;
if (t == null) {
root = newNode(key, value, null, null);
size = 1;
return null;
}
int cmp = comparify(key, t.key);
if (cmp < 0)
t = insertTree(t.left, key, value);
else if (cmp > 0)
t = insertTree(t.right, key, value);
else {
t.value = value;
return null;
}
root = balance(t);
return null;
}
private Entry<K, V> insertTree(Entry<K, V> t, K key, V value) {
if (t == null) {
return newNode(key, value, null, null);
}
int cmp = comparify(key, t.key);
if (cmp < 0)
t.left = insertTree(t.left, key, value);
else if (cmp > 0)
t.right = insertTree(t.right, key, value);
else {
t.value = value;
}
return t;
}
private int comparify(K key, K k) {
if (comparator != null)
return comparator.compare(key, k);
return ((Comparable<? super K>) key).compareTo(k);
}
// ...
}
`
TreeMap通过红黑树实现键值对的有序存储,put方法将键值对插入到红黑树中。
四、总结
本文深入解析了ADT源码中几个核心数据结构类的实现原理,包括ArrayList、LinkedList、HashMap和TreeMap。通过分析这些源码,开发者可以更好地理解Android数据结构的使用场景和性能特点,从而在开发过程中做出更合适的数据结构选择。