LinkedHashMap

439 阅读2分钟

有顺序的hashmap,默认是按插入顺序排序的

		LinkedHashMap<String,String> map = new LinkedHashMap();
		map.put("key1", "val1");
		map.put("key2", "val2");
		map.put("key3", "val3");
		map.put("key4", "val4");
		map.put("key5", "val5");
		// 进行读取操作
		map.get("key1");
		map.get("key4");
		map.get("key1");
		System.out.println(map);

打印结果: {key1=val1, key2=val2, key3=val3, key4=val4, key5=val5}
即使进行读取操作,map的顺序也不会改变.

LinkedHashMap有个特殊的构造方法,可以变更排序:

public LinkedHashMap(int initialCapacity, 
                         float loadFactor, 
                         boolean accessOrder) {
        super(initialCapacity, loadFactor);
        this.accessOrder = accessOrder;
    }
  • initialCapacity
    初始化容量,最好是2的幂次方,默认是16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
  • loadFactor 加载因子,容量达到最大容量的*loadFactor的时候会进行扩充。默认0.75
  • accessOrder 排序方式: false 基于插入顺序, true 基于访问顺序
		LinkedHashMap<String,String> map = new LinkedHashMap(16,0.7f,true);
		map.put("key1", "val1");
		map.put("key2", "val2");
		map.put("key3", "val3");
		map.put("key4", "val4");
		map.put("key5", "val5");
		
		map.get("key1");
		map.get("key4");
		map.get("key1");
		map.get("key3");
		System.out.println(map);

执行结果: {key2=val2, key5=val5, key4=val4, key1=val1, key3=val3} 可以看到最近访问的数据排在最后。

如果使用访问顺序排序的话,使用get访问数据,数据就会被移动到尾部。

如果是超过容量的情况下:

		LinkedHashMap<String,String> map = new LinkedHashMap(6,0.7f,true);
		map.put("key1", "val1");
		map.put("key2", "val2");
		map.put("key3", "val3");
		map.put("key4", "val4");
		map.put("key5", "val5");
		
		map.get("key1");
		map.get("key4");
		map.get("key1");
		map.get("key3");
		
		map.put("key6", "val6");
		map.put("key7", "val7");
		map.put("key8", "val8");
		System.out.println(map);

打印结果: {key2=val2, key5=val5, key4=val4, key1=val1, key3=val3, key6=val6, key7=val7, key8=val8}

可以看到容量已经超过6了。 修改下map,让超过容量进行删除操作:

    class LruCls<K,V> extends LinkedHashMap<K,V>{
	private int initialCapacity;
	public LruCls(int initialCapacity) {
		super(initialCapacity,0.75f,true);
		this.initialCapacity = initialCapacity;
	
	}
	
	// 超过容量就删除
	protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
        return size() > initialCapacity;
    }
}


		LinkedHashMap<String,String> map = new LruCls(6);
		map.put("key1", "val1");
		map.put("key2", "val2");
		map.put("key3", "val3");
		map.put("key4", "val4");
		map.put("key5", "val5");
		
		map.get("key1");
		map.get("key4");
		map.get("key1");
		map.get("key3");
		
		map.put("key6", "val6");
		map.put("key7", "val7");
		map.put("key8", "val8");
		System.out.println(map);

再执行: {key4=val4, key1=val1, key3=val3, key6=val6, key7=val7, key8=val8}

对照上面看见最先插入的数据没有了。这个就是LRU缓存的机制。