工具类:Map实现软/弱引用

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值