一、前言
这边基于hessian的com.caucho.hessian.util.IdentityIntMap实现简单的HashMap-从对象Key到整型int简单转换,并实现HashMap的基本API,具体参见如下代码说明
二、源码说明
package com.caucho.hessian.util;@b@@b@/**@b@ * The IntMap provides a simple hashmap from keys to integers. The API is@b@ * an abbreviation of the HashMap collection API.@b@ *@b@ * <p>The convenience of IntMap is avoiding all the silly wrapping of@b@ * integers.@b@ */@b@public class IdentityIntMap {@b@ /**@b@ * Encoding of a null entry. Since NULL is equal to Integer.MIN_VALUE,@b@ * it's impossible to distinguish between the two.@b@ */@b@ public final static int NULL = 0xdeadbeef; // Integer.MIN_VALUE + 1;@b@@b@ private Object []_keys;@b@ private int []_values;@b@@b@ private int _size;@b@ private int _prime;@b@@b@ /**@b@ * Create a new IntMap. Default size is 16.@b@ */@b@ public IdentityIntMap(int capacity)@b@ {@b@ _keys = new Object[capacity];@b@ _values = new int[capacity];@b@@b@ _prime = getBiggestPrime(_keys.length);@b@ _size = 0;@b@ }@b@@b@ /**@b@ * Clear the hashmap.@b@ */@b@ public void clear()@b@ {@b@ final Object []keys = _keys;@b@ final int []values = _values;@b@@b@ for (int i = keys.length - 1; i >= 0; i--) {@b@ keys[i] = null;@b@ values[i] = 0;@b@ }@b@@b@ _size = 0;@b@ }@b@ /**@b@ * Returns the current number of entries in the map.@b@ */@b@ public final int size()@b@ {@b@ return _size;@b@ }@b@@b@ /**@b@ * Puts a new value in the property table with the appropriate flags@b@ */@b@ public final int get(Object key)@b@ {@b@ int prime = _prime;@b@ int hash = System.identityHashCode(key) % prime;@b@ // int hash = key.hashCode() & mask;@b@@b@ final Object []keys = _keys;@b@@b@ while (true) {@b@ Object mapKey = keys[hash];@b@@b@ if (mapKey == null)@b@ return NULL;@b@ else if (mapKey == key)@b@ return _values[hash];@b@@b@ hash = (hash + 1) % prime;@b@ }@b@ }@b@@b@ /**@b@ * Puts a new value in the property table with the appropriate flags@b@ */@b@ public final int put(Object key, int value, boolean isReplace)@b@ {@b@ int prime = _prime;@b@ int hash = Math.abs(System.identityHashCode(key) % prime);@b@ // int hash = key.hashCode() % prime;@b@@b@ Object []keys = _keys;@b@@b@ while (true) {@b@ Object testKey = keys[hash];@b@@b@ if (testKey == null) {@b@ keys[hash] = key;@b@ _values[hash] = value;@b@@b@ _size++;@b@@b@ if (keys.length <= 4 * _size)@b@ resize(4 * keys.length);@b@@b@ return value;@b@ }@b@ else if (key != testKey) {@b@ hash = (hash + 1) % prime;@b@@b@ continue;@b@ }@b@ else if (isReplace){@b@ int old = _values[hash];@b@@b@ _values[hash] = value;@b@@b@ return old;@b@ }@b@ else {@b@ return _values[hash];@b@ }@b@ }@b@ }@b@@b@ /**@b@ * Removes a value in the property table.@b@ */@b@ public final void remove(Object key)@b@ {@b@ if (put(key, NULL, true) != NULL) {@b@ _size--;@b@ }@b@ }@b@@b@ /**@b@ * Expands the property table@b@ */@b@ private void resize(int newSize)@b@ {@b@ Object []keys = _keys;@b@ int values[] = _values;@b@@b@ _keys = new Object[newSize];@b@ _values = new int[newSize];@b@ _size = 0;@b@@b@ _prime = getBiggestPrime(_keys.length);@b@@b@ for (int i = keys.length - 1; i >= 0; i--) {@b@ Object key = keys[i];@b@ int value = values[i];@b@@b@ if (key != null && value != NULL) {@b@ put(key, value, true);@b@ }@b@ }@b@ }@b@@b@ protected int hashCode(Object value)@b@ {@b@ return System.identityHashCode(value);@b@ }@b@@b@ public String toString()@b@ {@b@ StringBuffer sbuf = new StringBuffer();@b@@b@ sbuf.append("IntMap[");@b@ boolean isFirst = true;@b@@b@ for (int i = 0; i <= _keys.length; i++) {@b@ if (_keys[i] != null) {@b@ if (! isFirst)@b@ sbuf.append(", ");@b@@b@ isFirst = false;@b@ sbuf.append(_keys[i]);@b@ sbuf.append(":");@b@ sbuf.append(_values[i]);@b@ }@b@ }@b@ sbuf.append("]");@b@@b@ return sbuf.toString();@b@ }@b@@b@ public static final int []PRIMES =@b@ {@b@ 1, /* 1<< 0 = 1 */@b@ 2, /* 1<< 1 = 2 */@b@ 3, /* 1<< 2 = 4 */@b@ 7, /* 1<< 3 = 8 */@b@ 13, /* 1<< 4 = 16 */@b@ 31, /* 1<< 5 = 32 */@b@ 61, /* 1<< 6 = 64 */@b@ 127, /* 1<< 7 = 128 */@b@ 251, /* 1<< 8 = 256 */@b@ 509, /* 1<< 9 = 512 */@b@ 1021, /* 1<<10 = 1024 */@b@ 2039, /* 1<<11 = 2048 */@b@ 4093, /* 1<<12 = 4096 */@b@ 8191, /* 1<<13 = 8192 */@b@ 16381, /* 1<<14 = 16384 */@b@ 32749, /* 1<<15 = 32768 */@b@ 65521, /* 1<<16 = 65536 */@b@ 131071, /* 1<<17 = 131072 */@b@ 262139, /* 1<<18 = 262144 */@b@ 524287, /* 1<<19 = 524288 */@b@ 1048573, /* 1<<20 = 1048576 */@b@ 2097143, /* 1<<21 = 2097152 */@b@ 4194301, /* 1<<22 = 4194304 */@b@ 8388593, /* 1<<23 = 8388608 */@b@ 16777213, /* 1<<24 = 16777216 */@b@ 33554393, /* 1<<25 = 33554432 */@b@ 67108859, /* 1<<26 = 67108864 */@b@ 134217689, /* 1<<27 = 134217728 */@b@ 268435399, /* 1<<28 = 268435456 */@b@ };@b@@b@ public static int getBiggestPrime(int value)@b@ {@b@ for (int i = PRIMES.length - 1; i >= 0; i--) {@b@ if (PRIMES[i] <= value)@b@ return PRIMES[i];@b@ }@b@@b@ return 2;@b@ }@b@}