在最近的面试中,我曾被多次问到,怎么实现一个最近最少使用(LRU)的缓存。缓存可以通过哈希表来实现,然而为这个缓存增加大小限制会变成另一个有意思的问题。现在我们看一下怎么实现。

最近最少使用缓存的回收

为了实现缓存回收,我们需要很容易做到:

  • 查询出最近最晚使用的项
  • 给最近使用的项做一个标记

链表可以实现这两个操作。检测最近最少使用的项只需要返回链表的尾部。标记一项为最近使用的项只需要从当前位置移除,然后将该项放置到头部。比较困难的事情是怎么快速的在链表中找到该项。

哈希表的帮助

看一下我们工具箱中的数据结构,哈希表可以在(消耗)常量的时间内索引到某个对象。如果我们创建一个形如key->链表节点的哈希表,我们就能够在常量时间内找到最近使用的节点。更甚的是,我们也能够在常量时间内判断节点的是否存在(或不存在);

找到这个节点后,我们就能将这个节点移动到链表的最前端,标记为最近使用的项了。

Java的捷径

据我所知,很少有一种编程语言的标准库中有通用的数据结构能提供上述功能的。这是一种混合的数据结构,我们需要在哈希表的基础上建立一个链表。但是Java已经为我们提供了这种形式的数据结构-LinkedHashMap!它甚至提供可覆盖回收策略的方法(见removeEldestEntry文档)。唯一需要我们注意的事情是,改链表的顺序是插入的顺序,而不是访问的顺序。但是,有一个构造函数提供了一个选项,可以使用访问的顺序(见文档)。

无需多说:

import java.util.LinkedHashMap;
import java.util.Map;

public LRUCache<K, V> extends LinkedHashMap<K, V> {
  private int cacheSize;

  public LRUCache(int cacheSize) {
    super(16, 0.75, true);
    this.cacheSize = cacheSize;
  }

  protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
    return size() >= cacheSize;
  }
}

10行Java代码实现最近被使用(LRU)缓存的更多相关文章

  1. 如何用70行Java代码实现深度神经网络算法

    http://www.tuicool.com/articles/MfYjQfV 如何用70行Java代码实现深度神经网络算法 时间 2016-02-18 10:46:17  ITeye 原文  htt ...

  2. 200行Java代码搞定计算器程序

    发现了大学时候写的计算器小程序,还有个图形界面,能够图形化展示表达式语法树,哈哈;) 只有200行Java代码,不但能够计算加减乘除,还能够匹配小括号~ 代码点评: 从朴素的界面配色到简单易懂错误提示 ...

  3. 只用120行Java代码写一个自己的区块链

    区块链是目前最热门的话题,广大读者都听说过比特币,或许还有智能合约,相信大家都非常想了解这一切是如何工作的.这篇文章就是帮助你使用 Java 语言来实现一个简单的区块链,用不到 120 行代码来揭示区 ...

  4. "如何用70行Java代码实现深度神经网络算法" 的delphi版本

     http://blog.csdn.net/hustjoyboy/article/details/50721535 "如何用70行Java代码实现深度神经网络算法" 的delphi ...

  5. 10 行 Python 代码实现模糊查询/智能提示

    10 行 Python 代码实现模糊查询/智能提示   1.导语: 模糊匹配可以算是现代编辑器(如 Eclipse 等各种 IDE)的一个必备特性了,它所做的就是根据用户输入的部分内容,猜测用户想要的 ...

  6. 10行Python代码计算汽车数量

    当你还是个孩子坐车旅行的时候,你玩过数经过的汽车的数目的游戏吗? 在这篇文章中,我将教你如何使用10行Python代码构建自己的汽车计数程序. 以下是环境及相应的版本库: Python版本 3.6.9 ...

  7. 10行C++代码实现高性能HTTP服务

    前言 是不是觉得C++写个服务太累,但又沉迷于C++的真香性能而无法自拔?作为一个老牌C++程序员(可以看我 github 上十几年前的C++项目:https://github.com/kevwan ...

  8. 只用120行Java代码写一个自己的区块链-3挖矿算法

    在本系列前两篇文章中,我们向大家展示了如何通过精炼的Java代码实现一个简单的区块链.包括生成块,验证块数据,广播通信等等,这一篇让我们聚焦在如何实现 PoW算法. 大家都无不惊呼比特币.以太坊及其他 ...

  9. 10 行 Python 代码写的模糊查询

    导语: 模糊匹配可以算是现代编辑器(在选择要打开的文件时)的一个必备特性了,它所做的就是根据用户输入的部分内容,猜测用户想要的文件名,并提供一个推荐列表供用户选择. 样例如下: Vim (Ctrl-P ...

随机推荐

  1. Deployment of VC2008 apps without installing anything

    If you create a default CRT/MFC application with VS2008, this application will not run on other comp ...

  2. HDU4647+贪心

    /* 贪心. 题意:给定一些点 一些边 点和边都有价值.现在A B 选点.求A-B的maxVal 思路:分割边.边的1/2分给两个端点. 如果这两个点被同一个人取,则ok:否则 做减法也行,对题意无影 ...

  3. android 动态改变listview的内容

    本文模拟:点击一个按钮,为已有的listview添加一行数据 <?xml version="1.0" encoding="utf-8"?> < ...

  4. [itint5]树中最大路径和

    http://www.itint5.com/oj/#13 要注意,一是空路径也可以,所以最小是0.然后要时刻注意路径顶多有两条子路径+根节点组成,所以更新全局最值时和返回上一级的值要注意分清. #in ...

  5. 数据段、代码段、堆栈段、BSS段

    在linux中,进程在内存中一般会分为5个段,用来存放从磁盘载入的程序代码,等. 这五个段分别是: BSS段: 通常用来存放程序中未初始化的全局变量的一块内存区域.属于静态内存分配. 问题:全局变量不 ...

  6. linux编译注解

    Linux kernel release 3.x <http://kernel.org/> These are the release notes for Linux version 3. ...

  7. VS2010调试 --指南 Reference from : http://blog.csdn.net/kingzone_2008/article/details/8133048

    1 导言 在软件开发周期中,测试和修正缺陷(defect,defect与bug的区别:Bug是缺陷的一种表现形式,而一个缺陷是可以引起多种Bug的) 的时间远多于写代码的时间.通常,debug是指发现 ...

  8. 【HDOJ】1448 The Treasure

    这就是个简单的bfs.真没什么好说的,三维的状态就可以了.每次预处理一下monster的位置,然后再恢复. /* 1924 */ #include <iostream> #include ...

  9. Number of Rectangles in a Grid

    Project Euler 85: Investigating the number of rectangles in a rectangular grid Number of Rectangles ...

  10. Android开发之少去踩坑,多走捷径【转】

    作者:gzjay,腾讯MIG无线产品部 高级工程师 最近一朋友提了几个Android问题让我帮忙写个小分享,我觉得对新人还是挺有帮助的,所以有了这个小分享. 1.目前, Android APP开发完成 ...