public class LRULinkedHashMap< K, V> extends LinkedHashMap < K, V> {
private final int maxCapacity;
private static final float DEFAULT_LOAD_FACTOR = 0.75f ;
private final Lock lock = new ReentrantLock ( ) ;
public LRULinkedHashMap ( int maxCapacity) {
super ( maxCapacity, DEFAULT_LOAD_FACTOR, true) ;
this. maxCapacity = maxCapacity;
}
@Override
protected boolean removeEldestEntry ( java. util. Map. Entry< K, V> eldest) {
return size ( ) > maxCapacity;
}
@Override
public boolean containsKey ( Object key) {
try {
lock. lock ( ) ;
return super. containsKey ( key) ;
} finally {
lock. unlock ( ) ;
}
}
@Override
public V get ( Object key) {
try {
lock. lock ( ) ;
return super. get ( key) ;
} finally {
lock. unlock ( ) ;
}
}
@Override
public V put ( K key, V value) {
try {
lock. lock ( ) ;
return super. put ( key, value) ;
} finally {
lock. unlock ( ) ;
}
}
public int size ( ) {
try {
lock. lock ( ) ;
return super. size ( ) ;
} finally {
lock. unlock ( ) ;
}
}
public void clear ( ) {
try {
lock. lock ( ) ;
super. clear ( ) ;
} finally {
lock. unlock ( ) ;
}
}
public Collection < Map. Entry< K, V>> getAll ( ) {
try {
lock. lock ( ) ;
return new ArrayList < Map. Entry< K, V>> ( super. entrySet ( ) ) ;
} finally {
lock. unlock ( ) ;
}
}
}
public class LRU< K, V> {
private Integer capcity;
private HashMap < K, Node> caches;
private Node first;
private Node last;
public LRU ( int size) {
capcity = size;
caches = new HashMap < > ( capcity) ;
}
public void put ( K key, V value) {
Node node = caches. get ( key) ;
if ( node == null) {
if ( caches. size ( ) >= capcity) {
caches. remove ( last. key) ;
removeLast ( ) ;
}
node = new Node ( key, value) ;
caches. put ( key, node) ;
} else {
node. value = value;
}
moveToHead ( node) ;
}
private void removeLast ( ) {
if ( last != null) {
last = last. pre;
if ( last == null) {
first = null;
} else {
last. next = null;
}
}
}
private void moveToHead ( Node node) {
if ( first == node) {
return ;
}
if ( node. next != null) {
node. next. pre = node. pre;
}
if ( node. pre != null) {
node. pre. next = node. next;
}
if ( node == last) {
last = last. pre;
}
if ( first == null || last == null) {
first = last = node;
return ;
}
node. next = first;
first. pre = node;
first = node;
first. pre = null;
}
public Object remove ( K key) {
Node node = caches. get ( key) ;
if ( node != null) {
if ( node. pre != null) {
node. pre. next = node. next;
}
if ( node. next != null) {
node. next. pre = node. pre;
}
if ( node == first) {
first = node. next;
}
if ( node == last) {
last = node. pre;
}
}
return caches. remove ( key) ;
}
public Object get ( K key) {
Node node = caches. get ( key) ;
if ( node == null) {
return null;
}
moveToHead ( node) ;
return node. value;
}
@Override
public String toString ( ) {
StringBuilder sb = new StringBuilder ( ) ;
Node node = first;
while ( node != null) {
sb. append ( String. format ( "%s:%s " , node. key, node. value) ) ;
node = node. next;
}
return sb. toString ( ) ;
}
public static void main ( String[ ] args) {
LRU < Integer, String> lru = new LRU < Integer, String> ( 5 ) ;
lru. put ( 1 , "a" ) ;
lru. put ( 2 , "b" ) ;
lru. put ( 3 , "c" ) ;
lru. put ( 4 , "d" ) ;
lru. put ( 5 , "e" ) ;
System. out. println ( "原始链表为:" + lru. toString ( ) ) ;
lru. get ( 4 ) ;
System. out. println ( "获取key为4的元素之后的链表:" + lru. toString ( ) ) ;
lru. put ( 6 , "f" ) ;
System. out. println ( "新添加一个key为6之后的链表:" + lru. toString ( ) ) ;
lru. remove ( 3 ) ;
System. out. println ( "移除key=3的之后的链表" + lru. toString ( ) ) ;
}
}
class Node{
Object key;
Object value;
Node pre;
Node next;
public Node ( Object key, Object value) {
this. key = key;
this. value = value;
}
}