Java源码阅读之HashMap
克隆与序列化
public Object clone(){
HashMap<K,V> result;
try{
result = (HashMap<K,V>)super.clone();
}catch(CloneNotSupportException e){
throw new InternalError(e);
}
result.reinitialize();
result.putMapEntries(this, false);
return result;
}
final float loadFactor(){
return loadFoctor;
}
final int capacity(){
return (table != null) ? table.length : (thershold > 0) ? thershold : DEFAULT_INITIAL_CAPACITY;
}
private void writeObject(java.io.ObjectOutputStream s) throws IOException{
int buckets = capacity();
s.defaultWriteObject();
s.writeInt(bucktes);
s.writeInt(size);
internalWriteEntries(s);
}
private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException{
s.defaultReadObject();
reinitialize();
if(loadFactor < 0 || Float.isNaa(loadFactor)){
throw new InvalidObjectException("Illegal load factor: " + loadFactor);
}
s.readInt();
int mappings = s.readInt();
if(mappings < 0){
throw new InvalidObjectException("Illegal mapping counts: " + mappings);
}else if(mappings > 0){
float lf = Math.min(Math.max(0.25f, loadFactor), 4.0f);
float fc = (float) mappings / lf + 1.0f;
int cap = ((fc < DEFAULT_INITIAL_CAPACITY) ? DEFAUT_INITIAL_CAPACITY : (fc > MAXMIUM_CAPACITY) : MAXMIUM_CAPACITY : tableSizeFor(fc));
float ft = (float) cap * lf;
threshold = ((cap < MAXMIUM_CAPACITY && ft < MAXMIUM_CAPACITY) ? (int)ft : MAXMIUM_CAPACITY);
Node<K,V>[] tab = (Node<K,V> [])new Node[cap];
for(int i = 0; i < mappings; i++){
K key = (K) s.readObject();
V value = (V) s.readObject();
putVal(hash(key), key, value, false, false);
}
}
}
void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException{
Node<K,V>[] tab;
if(size > 0 && (tab = table) != null){
for(int i = 0 ; i < tab.length; i ++){
for(Node<K,V> e = tab[i]; e != null; e = e.next){
s.writeObject(e.key);
s.writeObject(e.value);
}
}
}
}
迭代器
abstract class HashIterator{
Node<K,V> next;
Node<K,V> current;
int expectedModCount;
int index;
HashIterator(){
expectedModCount = modCount;
Node<K,V>[] t = table;
current = next = null;
index = 0;
do {} while(index < t.length && next=t[index++] != null);
}
public final boolean hasNext(){
return next != null;
}
final Node<K,V> nextNode(){
Node<K,V> t;
Node<K,V> e = next;
if(modCount != expectedModCount){
throw new ConcurrentComodificationException();
}
if(next == null){
throw new NoSuchElementException();
}
if((next = (current = e).next) == null && (t = table) != null){
do {} while(index < t.length && (next = t[index ++]) != null);
}
return e;
}
public final void remove(){
Node<K,V> p = current;
if(p == null){
throw new IllegalStateException();
}
if(modCount != expectedModCount){
throw new ConrrentComodificationException();
}
current = null;
K key = p.key;
removeNode(hash(key), key, null, false, false);
expectedModCount = modCount;
}
}
static class HashMapSpliterator<K,V>{
final HashMap<K,V> map;
Node<K,V> current;
int index;
int fence;
int est;
int expectedModCount;
HashMapSpliterator(HashMap<K,V> m, int origin, int fence, int est, int expectedModCount){
this.map = m;
this.index = origin;
this.fence = fence;
this.est = est;
this.expectedModCount = expectedModCount;
}
final int getFence(){
int hi;
if((hi = fence) < 0){
HashMap<K,V> m = map;
est = m.size();
expectedModCount = m.modCount;
Node<K,V>[] tab = m.table;
hi = fence = (tab == null) ? 0 : tab.length;
}
return hi;
}
public final long estimateSize(){
getFence();
return (long)est;
}
}
红黑数数据结构
static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V>{
TreeNode<K,V> parent;
TreeNode<K,V> left;
TreeNode<K,V> right;
TreeNode<K,V> prev;
boolean red;
TreeNode(int hash, K key, V value, Node<K,V> next){
super(hash, key, value, next);
}
final TreeNode<K,V> root(){
for(TreeNode<K,V> r = this, p;;){
if((p = r.parent) == null){
return r;
}
r = p;
}
}
static <K,V> void moveRootToFront(Node<K,V>[] tab, TreeNode<K,V> root){
int n;
if(root != null && tab != null && (n = tab.length) > 0){
int index = (n - 1) & root.hash;
TreeNode<K,V> first = (TreeNode<K,V>)tab[index];
if(root != first){
Node<K,V> rn;
tab[index] = root;
TreeNode<K,V> rp = root.prev;
if((rn = root.next) != null){
((TreeNode<K,V>)rn).prev = rp;
}
if(rp != null){
rp.next = rn;
}
if(first != null){
first.prev = root;
}
root.next = first;
root.prev = null;
}
}
}
}