mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
fix listener bug
This commit is contained in:
parent
7b7240aa4b
commit
9eb29695bf
@ -1,5 +1,6 @@
|
|||||||
package cn.hutool.core.cache.impl;
|
package cn.hutool.core.cache.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.mutable.Mutable;
|
||||||
import cn.hutool.core.map.FixedLinkedHashMap;
|
import cn.hutool.core.map.FixedLinkedHashMap;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -42,7 +43,13 @@ public class LRUCache<K, V> extends ReentrantCache<K, V> {
|
|||||||
this.timeout = timeout;
|
this.timeout = timeout;
|
||||||
|
|
||||||
//链表key按照访问顺序排序,调用get方法后,会将这次访问的元素移至头部
|
//链表key按照访问顺序排序,调用get方法后,会将这次访问的元素移至头部
|
||||||
cacheMap = new FixedLinkedHashMap<>(capacity);
|
final FixedLinkedHashMap<Mutable<K>, CacheObj<K, V>> fixedLinkedHashMap = new FixedLinkedHashMap<>(capacity);
|
||||||
|
fixedLinkedHashMap.setRemoveListener(entry -> {
|
||||||
|
if(null != listener){
|
||||||
|
listener.onRemove(entry.getKey().get(), entry.getValue().getValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cacheMap = fixedLinkedHashMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------- prune
|
// ---------------------------------------------------------------- prune
|
||||||
|
@ -1,21 +1,28 @@
|
|||||||
package cn.hutool.core.map;
|
package cn.hutool.core.map;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 固定大小的{@link LinkedHashMap} 实现<br>
|
* 固定大小的{@link LinkedHashMap} 实现<br>
|
||||||
* 注意此类非线程安全,由于{@link #get(Object)}操作会修改链表的顺序结构,因此也不可以使用读写锁。
|
* 注意此类非线程安全,由于{@link #get(Object)}操作会修改链表的顺序结构,因此也不可以使用读写锁。
|
||||||
*
|
*
|
||||||
* @author looly
|
|
||||||
*
|
|
||||||
* @param <K> 键类型
|
* @param <K> 键类型
|
||||||
* @param <V> 值类型
|
* @param <V> 值类型
|
||||||
|
* @author looly
|
||||||
*/
|
*/
|
||||||
public class FixedLinkedHashMap<K, V> extends LinkedHashMap<K, V> {
|
public class FixedLinkedHashMap<K, V> extends LinkedHashMap<K, V> {
|
||||||
private static final long serialVersionUID = -629171177321416095L;
|
private static final long serialVersionUID = -629171177321416095L;
|
||||||
|
|
||||||
/** 容量,超过此容量自动删除末尾元素 */
|
/**
|
||||||
|
* 容量,超过此容量自动删除末尾元素
|
||||||
|
*/
|
||||||
private int capacity;
|
private int capacity;
|
||||||
|
/**
|
||||||
|
* 移除监听
|
||||||
|
*/
|
||||||
|
private Consumer<java.util.Map.Entry<K, V>> removeListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
@ -45,10 +52,25 @@ public class FixedLinkedHashMap<K, V> extends LinkedHashMap<K, V> {
|
|||||||
this.capacity = capacity;
|
this.capacity = capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置自定义移除监听
|
||||||
|
*
|
||||||
|
* @param removeListener 移除监听
|
||||||
|
*/
|
||||||
|
public void setRemoveListener(final Consumer<Map.Entry<K, V>> removeListener) {
|
||||||
|
this.removeListener = removeListener;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean removeEldestEntry(final java.util.Map.Entry<K, V> eldest) {
|
protected boolean removeEldestEntry(final java.util.Map.Entry<K, V> eldest) {
|
||||||
//当链表元素大于容量时,移除最老(最久未被使用)的元素
|
//当链表元素大于容量时,移除最老(最久未被使用)的元素
|
||||||
return size() > this.capacity;
|
if (size() > this.capacity) {
|
||||||
|
if (null != removeListener) {
|
||||||
|
// 自定义监听
|
||||||
|
removeListener.accept(eldest);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package cn.hutool.core.cache;
|
package cn.hutool.core.cache;
|
||||||
|
|
||||||
import cn.hutool.core.cache.impl.LRUCache;
|
import cn.hutool.core.cache.impl.LRUCache;
|
||||||
|
import cn.hutool.core.lang.Console;
|
||||||
|
import cn.hutool.core.text.StrUtil;
|
||||||
import cn.hutool.core.thread.ThreadUtil;
|
import cn.hutool.core.thread.ThreadUtil;
|
||||||
import cn.hutool.core.util.RandomUtil;
|
import cn.hutool.core.util.RandomUtil;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
@ -64,4 +66,16 @@ public class LRUCacheTest {
|
|||||||
}
|
}
|
||||||
Assert.assertEquals("null123456789", sb2.toString());
|
Assert.assertEquals("null123456789", sb2.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void issue2647Test(){
|
||||||
|
final LRUCache<String, Integer> cache = CacheUtil.newLRUCache(3,1);
|
||||||
|
cache.setListener((key, value) -> Console.log("Start remove k-v, key:{}, value:{}", key, value));
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
cache.put(StrUtil.format("key-{}", i), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals(3, cache.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user