JDK提供的软/弱引用可以直接应用在某一对象,此处基于 JDK 提供的软/弱引用功能,实现Map的软/弱引用。(本质是map value值的软/弱引用)
实现有两个版本:
- JDK1.8之前的常规实现(继承实现)
- JDK1.8 FunctionInterface 版本
JDK1.8之前的常规实现
AbstractReferenceMap<K, V> 定义抽象接口,其有两个实现:
- SoftReferenceMap<K, V>
- WeakReferenceMap<K, V>
顾名思义,分别是 软/弱引用 的实现。
下面是具体代码:
AbstractReferenceMap
以 工程方法 的方式 在子类中 构建实例:
protected abstract Reference newInstance(V v);
package com.wj.util.ReferenceMap;
import java.lang.ref.Reference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
* Map 缓存,软引用/弱引用
* @param <K> key
* @param <V> value
*/
public abstract class AbstractReferenceMap<K, V> {
private Map<K, Reference<V>> refMap;
/**
* 以工厂方法新建实例
* @param v
* @return
*/
protected abstract Reference<V> newInstance(V v);
/**
* 构建空的 AbstractReferenceMap,初始 map capacity :16,扩容因子:0.75
*/
protected AbstractReferenceMap() {
refMap = new HashMap<>();
}
/**
* 构建空的 AbstractReferenceMap,初始 map capacity :16,扩容因子:initialCapacity
*
* @param initialCapacity the initial capacity.
* @throws IllegalArgumentException if the initial capacity is negative.
*/
protected AbstractReferenceMap(int initialCapacity) {
refMap = new HashMap<>(initialCapacity);
}
/**
* 构建空的 AbstractReferenceMap,初始 map capacity :initialCapacity,扩容因子:initialCapacity
*
* @param initialCapacity the initial capacity
* @param loadFactor the load factor
*/
protected AbstractReferenceMap(int initialCapacity, float loadFactor) {
refMap = new HashMap<>(initialCapacity, loadFactor);
}
public void putAll(Map<K, V> map) {
Objects.requireNonNull(map);
map.forEach((key, value) -> refMap.put(key, newInstance(value)));
}
public void put(K key, V value) {
Objects.requireNonNull(key);
refMap.put(key, newInstance(value));
}
public void clear() {
refMap.clear();
}
public void remove(K key) {
refMap.remove(key);
}
public V get(K key) {
if (refMap.containsKey(key)) {
return refMap.get(key).get();
}
return null;
}
public Set<K> keySet() {
return refMap.keySet();
}
public Collection<V> values() {
List<V> list = new ArrayList<>();
for (Reference<V> refItem : refMap.values()) {
V v = refItem.get();
if (v != null) {
list.add(v);
}
}
return list;
}
}
SoftReferenceMap
Map 的软引用,value值在内存溢出之前进行回收
package com.wj.util.ReferenceMap;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
/**
* Map 的软引用,内存溢出之前进行回收
* @param <K> key
* @param <V> value
*/
public class SoftReferenceMap<K, V> extends AbstractReferenceMap<K, V> {
@Override
protected Reference<V> newInstance(V v) {
return new SoftReference<>(v);
}
/**
* 构建空的 SoftReferenceMap,初始 map capacity :16,扩容因子:0.75
*/
public SoftReferenceMap() {
super();
}
/**
* 构建空的 SoftReferenceMap,初始 map capacity :16,扩容因子:initialCapacity
*
* @param initialCapacity the initial capacity.
* @throws IllegalArgumentException if the initial capacity is negative.
*/
public SoftReferenceMap(int initialCapacity) {
super(initialCapacity);
}
/**
* 构建空的 SoftReferenceMap,初始 map capacity :initialCapacity,扩容因子:initialCapacity
*
* @param initialCapacity the initial capacity
* @param loadFactor the load factor
*/
public SoftReferenceMap(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor);
}
}
WeakReferenceMap
package com.wj.util.ReferenceMap;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
public class WeakReferenceMap<K, V> extends AbstractReferenceMap<K, V> {
@Override
protected Reference<V> newInstance(V v) {
return new WeakReference<V>(v);
}
/**
* 构建空的 WeakReferenceMap,初始 map capacity :16,扩容因子:0.75
*/
public WeakReferenceMap() {
super();
}
/**
* 构建空的 WeakReferenceMap,初始 map capacity :16,扩容因子:initialCapacity
*
* @param initialCapacity the initial capacity.
* @throws IllegalArgumentException if the initial capacity is negative.
*/
public WeakReferenceMap(int initialCapacity) {
super(initialCapacity);
}
/**
* 构建空的 WeakReferenceMap,初始 map capacity :initialCapacity,扩容因子:initialCapacity
*
* @param initialCapacity the initial capacity
* @param loadFactor the load factor
*/
public WeakReferenceMap(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor);
}
}
JDK1.8 FunctionInterface 版本
java 1.8 引入 lambda 表达式,可简化上述实现。
package com.wj.util.ReferenceMap;
import java.lang.ref.Reference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
* Map 缓存,Java8 的实现方式
* @param <K> key
* @param <V> value
*/
public class ReferenceMap8<K, V> {
/**
* FunctionInterface,用于新建引用实例的工厂接口
* @param <V>
*/
public interface RefFactory<V> {
Reference<V> newInstance(V v);
}
/**
* 工厂接口新建 引用实例
*/
private RefFactory<V> refFactory;
/**
* 缓存
*/
private Map<K, Reference<V>> refMap;
/**
* 构建空的 ReferenceMap8 实例,初始 map capacity :16,扩容因子:0.75
*/
protected ReferenceMap8(RefFactory<V> refFactory) {
this.refFactory = refFactory;
this.refMap = new HashMap<>();
}
/**
* 构建空的 ReferenceMap8 实例,初始 map capacity :16,扩容因子:initialCapacity
*
* @param initialCapacity the initial capacity.
* @throws IllegalArgumentException if the initial capacity is negative.
*/
protected ReferenceMap8(RefFactory<V> refFactory, int initialCapacity) {
this.refFactory = refFactory;
this.refMap = new HashMap<>(initialCapacity);
}
/**
* 构建空的 ReferenceMap8 实例,初始 map capacity :initialCapacity,扩容因子:initialCapacity
*
* @param initialCapacity the initial capacity
* @param loadFactor the load factor
*/
protected ReferenceMap8(RefFactory<V> refFactory, int initialCapacity, float loadFactor) {
this.refFactory = refFactory;
this.refMap = new HashMap<>(initialCapacity, loadFactor);
}
public void putAll(Map<K, V> map) {
Objects.requireNonNull(map);
map.forEach((key, value) -> refMap.put(key, refFactory.newInstance(value)));
}
public V put(K key, V value) {
Objects.requireNonNull(key);
Reference<V> ref = refMap.put(key, refFactory.newInstance(value));
return Objects.requireNonNull(ref).get();
}
public void clear() {
refMap.clear();
}
public void remove(K key) {
refMap.remove(key);
}
public V get(K key) {
if (refMap.containsKey(key)) {
return refMap.get(key).get();
}
return null;
}
public Set<K> keySet() {
return refMap.keySet();
}
public Collection<V> values() {
List<V> list = new ArrayList<>();
for (Reference<V> refItem : refMap.values()) {
if (refItem != null) {
V v = refItem.get();
if (v != null) {
list.add(v);
}
}
}
return list;
}
}
使用方式:
package com.wj.util.ReferenceMap;
import java.lang.ref.SoftReference;
/**
* 构建 Map 软/弱引用的方式
*/
public class Test {
public static void main(String[] args) {
AbstractReferenceMap<String, Object> map = new SoftReferenceMap<>();
@SuppressWarnings("unchecked")
ReferenceMap8<String, Object> map2 = new ReferenceMap8(SoftReference::new);
}
}
java的软/弱引用参考:https://www.cnblogs.com/yw-ah/p/5830458.html