昨天闲的蛋疼啊,就看看了集合框架的源码,忽然看到了这么一个玩意儿,arraymap,好奇就百度了一下,大概也了解了一下,今天就一言不合写博客了,知识在于积累啊。
1 看看hashmap是怎么回事
//无参数的构造,第一个表示默认的容器大小
public HashMap() {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
}
这行代码很重要
transient HashMapEntry<K, V>[] table = (HashMapEntry<K, V>[]) EMPTY_TABLE;
这个table实际上就是我们所说的hashMap,hashMap的实质就是一个数组,而这个数组里面的元素就是HashMapEntry,我们的kv就是封装到这个元素里面。下面我们再看看他的put方法是怎么回事:
public V put(K key, V value) {
//EMPTY_TABLE指的是一个空的数组
if (table == EMPTY_TABLE) {
//创建数组
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = sun.misc.Hashing.singleWordWangJenkinsHash(key);
int i = indexFor(hash, table.length);
for (HashMapEntry<K, V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
//添加元素
addEntry(hash, key, value, i);
return null;
}
table = new HashMapEntry[capacity]; 这行代码就是初始化数组;
void createEntry(int hash, K key, V value, int bucketIndex) {
HashMapEntry<K, V> e = table[bucketIndex];
table[bucketIndex] = new HashMapEntry<>(hash, key, value, e);
size++;
}
没错,就是在这个方法里面添加元素,没调用一次put方法就要new一个HashMapEntry对象,这样非常消耗性能;
下面看看ArrayMap的put:
无参构造里面的:
static final int[] EMPTY_INTS = new int[0];
static final long[] EMPTY_LONGS = new long[0];
static final Object[] EMPTY_OBJECTS = new Object[0];
mHashes = ContainerHelpers.EMPTY_INTS;
mArray = ContainerHelpers.EMPTY_OBJECTS;
你没看错,他是维持的2个数组,不想hashMap每次都要new
mHashes[index] = hash;
mArray[index<<1] = key;
mArray[(index<<1)+1] = value;
mSize++;
好了,不多说了,一个放弃hashMap了;