简体中文简体中文
EnglishEnglish
简体中文简体中文

深入解析ADT源码:揭秘Android数据结构的

2025-01-21 01:46:55

随着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数据结构的使用场景和性能特点,从而在开发过程中做出更合适的数据结构选择。