android的hashmap 原理以及源码探究
Android基础-Android中的HashMap浅析
Android java中的ArrayList的原理和实现
HashMap源码解析如下
transient arrayList 持久化
static class HashMapEntry<K, V> implements Entry<K, V> {
final K key;
V value;
final int hash;
HashMapEntry<K, V> next;
transient HashMapE
private static final Entry[] EMPTY_TABLE
= new HashMapEntry[MINIMUM_CAPACITY >>> 1];
ntry<K, V>[] table;
for (int j = 0; j < oldCapacity; j++) {
for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
int index = hash & (tab.length - 1); //这里等价于 int index = hash%tab.length 。
//只不过运算速度相比于取余,速度更快。不过必须确保tab.length为2的n次方
tab = doubleCapacity(); //将数组扩容
index = hash & (tab.length - 1); //根据新的数组长度,计算新的index值
HashMapEntry<K,V>[] tab
addNewEntry(key, value, hash, index); //将数据保存
void addNewEntry(K key, V value, int hash, int index) {
table[index] = new HashMapEntry<K, V>(key, value, hash, table[index]);
}
HashMapEntry(K key, V value, int hash, HashMapEntry<K, V> next) {
重点难点一
int index = hash & (tab.length - 1); //这里等价于 int index = hash%tab.length 。
//只不过运算速度相比于取余,速度更快。不过必须确保tab.length为2的n次方
重点难点二
tab = doubleCapacity(); //将数组扩容
private HashMapEntry<K, V>[] doubleCapacity() {
HashMapEntry<K, V>[] newTable = makeTable(newCapacity);
int highBit = e.hash & oldCapacity;
HashMapEntry<K, V> broken = null;
newTable[j | highBit] = e;
for (HashMapEntry<K, V> n = e.next; n != null; e = n, n = n.next) {
int nextHighBit = n.hash & oldCapacity;
if (nextHighBit != highBit) {
if (broken == null)
newTable[j | nextHighBit] = n;
else
broken.next = n;
broken = e;
highBit = nextHighBit;
}
}
if (broken != null)
broken.next = null;
}
private HashMapEntry<K, V>[] makeTable(int newCapacity) {
@SuppressWarnings("unchecked") HashMapEntry<K, V>[] newTable
= (HashMapEntry<K, V>[]) new HashMapEntry[newCapacity];
table = newTable;
threshold = (newCapacity >> 1) + (newCapacity >> 2); // 3/4 capacity
return newTable;
}
HashMap
private static final Entry[] EMPTY_TABLE
= new HashMapEntry[MINIMUM_CAPACITY >>> 1];
HashMapEntry<K, V>[] tab = (HashMapEntry<K, V>[]) EMPTY_TABLE;
HashSet
D:/sdk/sdk2/sdk2/sources/android-21/java/util/HashSet.java:34
transient HashMap<E, HashSet<E>> backingMap;
public Object clone() {
try {
HashSet<E> clone = (HashSet<E>) super.clone();
clone.backingMap = (HashMap<E, HashSet<E>>) backingMap.clone();
return clone;
} catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
}
Map map = new HashMap();
map.put("1",2);
map.put("2","2");
map.put("3","2");
Map map1 = new HashMap();
map1.put("1","2");
map1.put("2","2");
map1.put("3","2");
map.put("1",map1);
@Override public V put(K key, V value) {
if (key == null) {
return putValueForNullKey(value);
}
int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);
for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
if (e.hash == hash && key.equals(e.key)) {
preModify(e);
V oldValue = e.value;
e.value = value;
return oldValue;
}
}
// No entry for (non-null) key is present; create one
modCount++;
if (size++ > threshold) {
tab = doubleCapacity();
index = hash & (tab.length - 1);
}
addNewEntry(key, value, hash, index);
return null;
}
int hash = Collections.secondaryHash(key);
addNewEntry(key,value,hash,index);
private HashMapEntry<K, V>[] doubleCapacity() {
HashMapEntry<K, V>[] oldTable = table;
int oldCapacity = oldTable.length;
if (oldCapacity == MAXIMUM_CAPACITY) {
return oldTable;
}
int newCapacity = oldCapacity * 2;
HashMapEntry<K, V>[] newTable = makeTable(newCapacity);
if (size == 0) {
return newTable;
}
for (int j = 0; j < oldCapacity; j++) {
/*
* Rehash the bucket using the minimum number of field writes.
* This is the most subtle and delicate code in the class.
*/
HashMapEntry<K, V> e = oldTable[j];
if (e == null) {
continue;
}
int highBit = e.hash & oldCapacity;
HashMapEntry<K, V> broken = null;
newTable[j | highBit] = e;
for (HashMapEntry<K, V> n = e.next; n != null; e = n, n = n.next) {
int nextHighBit = n.hash & oldCapacity;
if (nextHighBit != highBit) {
if (broken == null)
newTable[j | nextHighBit] = n;
else
broken.next = n;
broken = e;
highBit = nextHighBit;
}
}
if (broken != null)
broken.next = null;
}
return newTable;
}
HashMapEntry<K,V> e =oldTable[j];
int highBit = e.hash & oldCapacity;
newTable[j | highBit] = e;
int nextHighBit = n.hash & oldCapacity;
newTable[j | nextHighBit] = n;
@Override public V remove(Object key) {
if (key == null) {
return removeNullKey();
}
int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
int index = hash & (tab.length - 1);
for (HashMapEntry<K, V> e = tab[index], prev = null;
e != null; prev = e, e = e.next) {
if (e.hash == hash && key.equals(e.key)) {
if (prev == null) {
tab[index] = e.next;
} else {
prev.next = e.next;
}
modCount++;
size--;
postRemove(e);
return e.value;
}
}
return null;
}
tab[index] = e.next;
prev.next = e.next;
public V get(Object key) {
if (key == null) {
HashMapEntry<K, V> e = entryForNullKey;
return e == null ? null : e.value;
}
int hash = Collections.secondaryHash(key);
HashMapEntry<K, V>[] tab = table;
for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
e != null; e = e.next) {
K eKey = e.key;
if (eKey == key || (e.hash == hash && key.equals(eKey))) {
return e.value;
}
}
return null;
}
HashMapEntry<K,V> e
HashMapEntry<K,V> []tab
如下为 ArrayList源码解析
下面是 System.arrayCopy的源代码声明 :
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
代码解释:
Object src : 原数组
int srcPos : 从元数据的起始位置开始
Object dest : 目标数组
int destPos : 目标数组的开始起始位置
int length : 要copy的数组的长度
比如 :我们有一个数组数据 byte[] srcBytes = new byte[]{2,4,0,0,0,0,0,10,15,50}; // 源数组
byte[] destBytes = new byte[5]; // 目标数组
我们使用System.arraycopy进行转换(copy)
System.arrayCopy(srcBytes,0,destBytes ,0,5)
上面这段代码就是 : 创建一个一维空数组,数组的总长度为 12位,然后将srcBytes源数组中 从0位 到 第5位之间的数值 copy 到 destBytes目标数组中,
在目标数组的第0位开始放置.
那么这行代码的运行效果应该是 2,4,0,0,0,
public ArrayList(Collection<? extends E> collection) {
if (collection == null) {
throw new NullPointerException("collection == null");
}
Object[] a = collection.toArray();
if (a.getClass() != Object[].class) {
Object[] newArray = new Object[a.length];
System.arraycopy(a, 0, newArray, 0, a.length);
a = newArray;
}
array = a;
size = a.length;
}
Object[] newArray = new Object[a.length];
arrayCopy
transient Object[] array;
@Override public boolean add(E object) {
Object[] a = array;
int s = size;
if (s == a.length) {
Object[] newArray = new Object[s +
(s < (MIN_CAPACITY_INCREMENT / 2) ?
MIN_CAPACITY_INCREMENT : s >> 1)];
System.arraycopy(a, 0, newArray, 0, s);
array = a = newArray;
}
a[s] = object;
size = s + 1;
modCount++;
return true;
}
private static final int MIN_CAPACITY_INCREMENT = 12;
@Override public void add(int index, E object) {
Object[] a = array;
int s = size;
if (index > s || index < 0) {
throwIndexOutOfBoundsException(index, s);
}
if (s < a.length) {
System.arraycopy(a, index, a, index + 1, s - index);
} else {
// assert s == a.length;
Object[] newArray = new Object[newCapacity(s)];
System.arraycopy(a, 0, newArray, 0, index);
System.arraycopy(a, index, newArray, index + 1, s - index);
array = a = newArray;
}
a[index] = object;
size = s + 1;
modCount++;
}
int newCapacity = newCapacity(newSize - 1); // ~33% growth room
@Override public E remove(int index) {
Object[] a = array;
int s = size;
if (index >= s) {
throwIndexOutOfBoundsException(index, s);
}
@SuppressWarnings("unchecked") E result = (E) a[index];
System.arraycopy(a, index + 1, a, index, --s - index);
a[s] = null; // Prevent memory leak
size = s;
modCount++;
return result;
}
@Override public boolean remove(Object object) {
Object[] a = array;
int s = size;
if (object != null) {
for (int i = 0; i < s; i++) {
if (object.equals(a[i])) {
System.arraycopy(a, i + 1, a, i, --s - i);
a[s] = null; // Prevent memory leak
size = s;
modCount++;
return true;
}
}
} else {
for (int i = 0; i < s; i++) {
if (a[i] == null) {
System.arraycopy(a, i + 1, a, i, --s - i);
a[s] = null; // Prevent memory leak
size = s;
modCount++;
return true;
}
}
}
return false;
}
如下为LinkedList源码解析
LinkedList(): 在实现中采用链表数据结构。插入和删除速度快,访问速度慢。
public void add(ET object) {
if (expectedModCount == list.modCount) {
Link<ET> next = link.next;
Link<ET> newLink = new Link<ET>(object, link, next);
link.next = newLink;
next.previous = newLink;
link = newLink;
lastLink = null;
pos++;
expectedModCount++;
list.size++;
list.modCount++;
} else {
throw new ConcurrentModificationException();
}
}
private static final class Link<ET> {
ET data;
Link<ET> previous, next;
Link(ET o, Link<ET> p, Link<ET> n) {
data = o;
previous = p;
next = n;
}
}