Memcached的实现核心就是一个LRU算法,它使用双端链表实现。
下面也是一个简单的用双端链表实现的单例LRU Cache,大家可以根据自己的需要添加一些方法。
package lruCache;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
public class LRUCache {
private static Map<Object, DoubleLinkedListNode> map = new HashMap<Object, DoubleLinkedListNode>();
private DoubleLinkedListNode head;
private DoubleLinkedListNode end;
private int len;
private int capacity;
private static LRUCache singleton = null;
public static LRUCache getInstance(int capacity){
if(null == singleton){
singleton = new LRUCache(capacity);
}
return singleton;
}
private LRUCache(int capacity) {
this.capacity = capacity;
len = 0;
}
public Object get(Object key) {
if(map.containsKey(key)){
DoubleLinkedListNode latest = map.get(key);
removeFromList(latest);
setHead(latest);
return latest.val;
}
else{
return null;
}
}
public void set(Object key, Object value) {
if (map.containsKey(key)) {
DoubleLinkedListNode oldNode = map.get(key);
oldNode.val = value;
removeFromList(oldNode);
setHead(oldNode);
} else {
DoubleLinkedListNode newNode =
new DoubleLinkedListNode(key, value);
if (len < capacity) {
setHead(newNode);
map.put(key, newNode);
len++;
} else {
map.remove(end.key);
end = end.pre;
if (end != null) {
end.post = null;
}
setHead(newNode);
map.put(key, newNode);
}
}
}
private void removeFromList(DoubleLinkedListNode node){
if(node.pre != null){
node.pre.post = node.post;
}
else{
head = node.post;
}
if(node.post != null){
node.post.pre = node.pre;
}
else{
end = node.pre;
}
}
private void setHead(DoubleLinkedListNode node){
node.post = head;
node.pre = null;
if (head != null) {
head.pre = node;
}
head = node;
if (end == null) {
end = node;
}
}
//返回当前Cache中key的集合
public Set<Object> keySet(){
Set<Object> res = new LinkedHashSet<Object>();
DoubleLinkedListNode cur = head;
while(null != cur){
res.add(cur.key);
cur = cur.post;
}
return res;
}
private class DoubleLinkedListNode{
Object key;
Object val;
DoubleLinkedListNode pre;
DoubleLinkedListNode post;
DoubleLinkedListNode(Object key, Object value){
this.key = key;
val = value;
}
}
}
测试类:
package lruCache;
import java.util.Set;
public class LRUCacheDemo {
public static void main(String[] args){
//新建一个容量为5的LRUCache
LRUCache lruCache = LRUCache.getInstance(5);
lruCache.set("1", "yi");
lruCache.set("1", "yiyi");
Set<Object> keySet = lruCache.keySet();
lruCache.set("2", "er");
lruCache.set("3", "san");
lruCache.set("4", "si");
lruCache.set("5", "wu");
lruCache.set("6", "liu");
Set<Object> keySet2 = lruCache.keySet();
}
}
分享到:
相关推荐
本主题主要关注两种特殊类型的链表——双端链表(Double-ended LinkedList)和双向链表(Bidirectional LinkedList),并以Java语言实现为例进行讲解。 双端链表,也称为双链表,是一种允许在链表的两端进行插入和...
双端链表与单链表相似,但它提供了更多的灵活性,因为它允许从两个方向遍历链表。在Java中,双端链表可以在单链表的基础上添加一个指向前一个节点的引用,例如`previous`。这样,我们不仅可以访问下一个节点,还可以...
基数排序(radix sort)又称桶排序(bucket sort),相对于常见的比较排序,基数排序是一种分配式排序,需要将关键字...为了尽可能少的消耗复制时占用的空间,桶的数据结构选择链表,为了构造队列,选择使用双向列表。
3. **入栈操作**:push函数,对数组实现需要检查是否达到数组边界,对链表实现则需创建新节点并链接到链表尾部。 4. **出栈操作**:pop函数,数组实现直接改变栈顶指针,链表实现需找到链表头并移除。 5. **查看栈顶...
Java数据结构之双端链表原理与实现方法 Java数据结构中,双端链表是一种常用的数据结构,它可以实现链表的插入、删除、遍历等操作。双端链表的特点是,它有两个指针,一个指向链表的头节点,另一个指向链表的尾节点...
在 Java 中,LinkedList 的内部使用双端链表队列原理实现,而 ArrayList 的内部使用双端数组队列原理实现。 Java 实现自定义双端队列可以通过链表和数组两种方式实现,双端队列可以充当单端队列,也可以用于充当栈...
链表实现集合运算 链表实现集合交并差运算
本项目是关于“用链表实现集合并集”的C++课程设计,主要目的是掌握集合操作以及如何利用链表数据结构高效地实现这些操作。 首先,我们需要了解集合的基本概念。集合是一个无序且不包含重复元素的数学结构。在...
* 基于双向链表实现双端队列结构 */ package dsa; public class Deque_DLNode implements Deque { protected DLNode header;//指向头节点(哨兵) protected DLNode trailer;//指向尾节点(哨兵) protected ...
本项目以"用数据结构-链表实现通讯录管理系统"为主题,通过C语言实现了这一功能,旨在帮助用户管理他们的联系人信息。下面我们将深入探讨这个系统所涉及的主要知识点。 首先,我们来了解**链表**这一数据结构。链表...
自定义双端队列的基本思想是使用动态数组或链表作为底层数据结构。这里我们以动态数组为例,因为它提供了更好的空间效率和随机访问性能。一个简单的C++实现可能包括以下几个关键操作: 1. **初始化**:创建一个空的...
本话题主要探讨了两种常用的数据结构——数组和链表——在实现队列这一线性数据结构时的应用。队列是一种先进先出(First In First Out, FIFO)的数据结构,它的主要操作包括入队(enqueue)、出队(dequeue)以及...
链表作为一种灵活的数据结构,常被用于实现动态菜单系统,以适应不同场景和功能的变化。下面将详细阐述如何使用链表来实现STM32上的多级菜单及其相关知识点。 首先,我们需要理解链表的基本概念。链表不同于数组,...
在本课程设计中,学生被要求使用C语言来实现一个基于双向循环链表的通讯录系统。这个系统应具备添加、插入、删除、查询和统计联系人信息的基本功能,并且要具备良好的用户界面和错误处理机制,以确保系统的稳定性和...
C语言链表实现的贪吃蛇小游戏。.zipC语言链表实现的贪吃蛇小游戏。.zipC语言链表实现的贪吃蛇小游戏。.zipC语言链表实现的贪吃蛇小游戏。.zipC语言链表实现的贪吃蛇小游戏。.zipC语言链表实现的贪吃蛇小游戏。.zipC...
### 使用链表实现图书管理系统的知识点 #### 一、链表基本概念 链表是一种常见的数据结构,由一系列节点组成,每个节点包含实际存储的数据和一个指向下一个节点的引用(指针)。在本例中,链表用于实现图书管理系统...
本篇将深入探讨如何用链表来实现线性表,并通过提供的`ChainList.java`和`ListInterface.java`文件来理解其实现细节。 首先,线性表具有顺序访问的特点,其元素可以通过索引进行访问。链表是一种非连续存储结构,每...
本主题关注的是如何使用链表来实现两个多项式的相加。在这个过程中,我们将深入理解链表的特性,并探讨如何利用这些特性来处理数学中的多项式运算。 首先,让我们了解一下链表的基本概念。链表是一种线性数据结构,...
本文将深入探讨如何使用C++通过链表数据结构来实现一元多项式的加法操作。一元多项式通常由一系列的系数和指数对组成,例如2x^3 + 5x^2 - 3x + 1。这种表达式可以通过链表的节点来表示,每个节点存储一个系数和对应...
栈的实现(C语言)数组实现以及链表实现源码,以及各个功能测试代码函数等 和后缀式转前缀式的用例