ArrayMap结构:
arraymap是数组结构,里面并没有entry结构,而是由两个数组来维护的,mHashes数组中保存的是每一项的HashCode值,mArray中就是键值对,每两个元素代表一个键值对;
SparseArray结构:
它内部则通过两个数组来进行数据存储的,一个存储key(只能为int值),另外一个存储value,为了优化性能,它内部对数据还采取了压缩的方式来表示稀疏数组的数据;put和get时都是按照二分查找进行的,在数据量小的情况下,查找有着较高效率;
而hashmap是数组+链表结构;
arraymap,sparsearay和hashmap区别:
查找效率
hashmap:通过hashcode计算的index直接拿到值;
arraymap:是通过二分法查找拿到值;
sparsearray:通过二分法put和get,适合数据量小场景;
因此数据量大的时候用hashmap;
扩容效率: hashmap通过new 去申请空间并进行再哈希法;而arraymap直接调用system.arraycopy,效率更高;
构造源码:
public class ArrayMap<K, V> extends AbstractMap<K, V> implements Map<K, V> {
/**
* 默认数组长度
*/
private static final int DEFAULT_LENGTH = 16;
/**
* 数据存储的数组
*/
private Node[] tables;
/**
* map内元素的数量
*/
private int index;
public ArrayMap() {
this(DEFAULT_LENGTH);
}
/**
* @param length 初始化长度
*/
public ArrayMap(int length) {
if (length <= 0) {
throw new IllegalArgumentException("非法参数");
}
tables = new Node[length];
}
/**
* 从Map中获取元素
*
* @param key 获取的对象
* @return 查询得到的对象,若是不存在,则返回Null
*/
@Override
public V get(Object key) {
V value = null;
for (int i = 0; i < index; i++) {
Node<K, V> node = tables[i];
K nodeKey = node.getKey();
if ((nodeKey == null && key == null) || (key != null && key.equals(nodeKey))) {
return node.getValue();
}
}
return value;
}
/**
* 在Map中放置Key-Value对
*
* @param key 放置的Key
* @param value 放置的Value
* @return 返回value
*/
@Override
public V put(K key, V value) {
if (index >= tables.length) {
throw new ArrayIndexOutOfBoundsException("数组越界");
}
for (int i = 0; i < index; i++) {
Node<K, V> node = tables[i];
K nodeKey = node.getKey();
if ((nodeKey == null && key == null) || (key != null && key.equals(nodeKey))) {
node.setValue(value);
return value;
}
}
tables[index] = new Node(key, value);
if (++index == tables.length) {
resize();
}
return value;
}
@Override
public int size() {
return index;
}
@Override
public void clear() {
index = 0;
int parLength = tables.length;
tables = new Node[parLength];
}
/**
* 尚未实现的方法
*
* @return null
*/
@Override
public Set<Entry<K, V>> entrySet() {
Set<Entry<K, V>> set = new HashSet<>();
for (int i = 0; i < index; i++) {
Node<K, V> node = tables[i];
set.add(node);
}
return set;
}
/**
* 数组扩容
*/
private void resize() {
int parLength = tables.length;
Node<K, V>[] newTable = new Node[parLength * 3 / 2];
for (int i = 0; i < parLength; i++) {
newTable[i] = tables[i];
}
tables = newTable;
}
class Node<K, V> implements Entry<K, V> {
private K key;
private V value;
public Node(K key, V value) {
this.key = key;
this.value = value;
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
@Override
public V setValue(V value) {
this.value = value;
return value;
}
@Override
public String toString() {
return key + "=" + value;
}
}
}