Android提供的LruCache类简介(1)

  1. If your cached values hold resources that need to be explicitly released,

  2. * override {@link #entryRemoved}.

  3. * 如果你cache的某个值需要明确释放,重写entryRemoved()

  4. If a cache miss should be computed on demand for the corresponding keys,

  5. * override {@link #create}. This simplifies the calling code, allowing it to

  6. * assume a value will always be returned, even when there’s a cache miss.

  7. * 如果key相对应的item丢掉啦,重写create().这简化了调用代码,即使丢失了也总会返回。

  8. By default, the cache size is measured in the number of entries. Override

  9. * {@link #sizeOf} to size the cache in different units. For example, this cache

  10. * is limited to 4MiB of bitmaps: 默认cache大小是测量的item的数量,重写sizeof计算不同item的

  11. *  大小。

  12.    {@code

  13. *   int cacheSize = 4 * 1024 * 1024; // 4MiB

  14. *   LruCache<String, Bitmap> bitmapCache = new LruCache<String, Bitmap>(cacheSize) {

  15. *       protected int sizeOf(String key, Bitmap value) {

  16. *           return value.getByteCount();

  17. *       }

  18. *   }}

  19. *

  20. This class is thread-safe. Perform multiple cache operations atomically by

  21. * synchronizing on the cache: 

       {@code

  22. *   synchronized (cache) {

  23. *     if (cache.get(key) == null) {

  24. *         cache.put(key, value);

  25. *     }

  26. *   }}

  27. *

  28. This class does not allow null to be used as a key or value. A return

  29. * value of null from {@link #get}, {@link #put} or {@link #remove} is

  30. * unambiguous: the key was not in the cache.

  31. * 不允许key或者value为null

  32. *  当get(),put(),remove()返回值为null时,key相应的项不在cache中

  33. */

  34. public class LruCache<K, V> {

  35. private final LinkedHashMap<K, V> map;

  36. /** Size of this cache in units. Not necessarily the number of elements. */

  37. private int size; //已经存储的大小

  38. private int maxSize; //规定的最大存储空间

  39. private int putCount;  //put的次数

  40. private int createCount;  //create的次数

  41. private int evictionCount;  //回收的次数

  42. private int hitCount;  //命中的次数

  43. private int missCount;  //丢失的次数

  44. /**

  45. * @param maxSize for caches that do not override {@link #sizeOf}, this is

  46. *     the maximum number of entries in the cache. For all other caches,

  47. *     this is the maximum sum of the sizes of the entries in this cache.

  48. */

  49. public LruCache(int maxSize) {

  50. if (maxSize <= 0) {

  51. throw new IllegalArgumentException(“maxSize <= 0”);

  52. }

  53. this.maxSize = maxSize;

  54. this.map = new LinkedHashMap<K, V>(0, 0.75f, true);

  55. }

  56. /**

  57. * Returns the value for {@code key} if it exists in the cache or can be

  58. * created by {@code #create}. If a value was returned, it is moved to the

  59. * head of the queue. This returns null if a value is not cached and cannot

  60. * be created. 通过key返回相应的item,或者创建返回相应的item。相应的item会移动到队列的头部,

  61. * 如果item的value没有被cache或者不能被创建,则返回null。

  62. */

  63. public final V get(K key) {

  64. if (key == null) {

  65. throw new NullPointerException(“key == null”);

  66. }

  67. V mapValue;

  68. synchronized (this) {

  69. mapValue = map.get(key);

  70. if (mapValue != null) {

  71. hitCount++;  //命中

  72. return mapValue;

  73. }

  74. missCount++;  //丢失

  75. }

  76. /*

  77. * Attempt to create a value. This may take a long time, and the map

  78. * may be different when create() returns. If a conflicting value was

  79. * added to the map while create() was working, we leave that value in

  80. * the map and release the created value.

  81. * 如果丢失了就试图创建一个item

  82. */

  83. V createdValue = create(key);

  84. if (createdValue == null) {

  85. return null;

  86. }

  87. synchronized (this) {

  88. createCount++;//创建++

  89. mapValue = map.put(key, createdValue);

  90. if (mapValue != null) {

  91. // There was a conflict so undo that last put

  92. //如果前面存在oldValue,那么撤销put()

  93. map.put(key, mapValue);

  94. } else {

  95. size += safeSizeOf(key, createdValue);

  96. }

  97. }

  98. if (mapValue != null) {

  99. entryRemoved(false, key, createdValue, mapValue);

  100. return mapValue;

  101. } else {

  102. trimToSize(maxSize);

  103. return createdValue;

  104. }

  105. }

  106. /**

  107. * Caches {@code value} for {@code key}. The value is moved to the head of

  108. * the queue.

  109. *

  110. * @return the previous value mapped by {@code key}.

  111. */

  112. public final V put(K key, V value) {

  113. if (key == null || value == null) {

  114. throw new NullPointerException(“key == null || value == null”);

  115. }

  116. V previous;

  117. synchronized (this) {

  118. putCount++;

  119. size += safeSizeOf(key, value);

  120. previous = map.put(key, value);

  121. if (previous != null) {  //返回的先前的value值

  122. size -= safeSizeOf(key, previous);

  123. }

  124. }

  125. if (previous != null) {

  126. entryRemoved(false, key, previous, value);

  127. }

  128. trimToSize(maxSize);

  129. return previous;

  130. }

  131. /**

  132. * @param maxSize the maximum size of the cache before returning. May be -1

  133. *     to evict even 0-sized elements.

  134. *  清空cache空间

  135. */

  136. private void trimToSize(int maxSize) {

  137. while (true) {

  138. K key;

  139. V value;

  140. synchronized (this) {

  141. if (size < 0 || (map.isEmpty() && size != 0)) {

  142. throw new IllegalStateException(getClass().getName()

  143. + “.sizeOf() is reporting inconsistent results!”);

  144. }

  145. if (size <= maxSize) {

  146. break;

  147. }

  148. Map.Entry<K, V> toEvict = map.eldest();

  149. if (toEvict == null) {

  150. break;

  151. }

  152. key = toEvict.getKey();

  153. value = toEvict.getValue();

  154. map.remove(key);

  155. size -= safeSizeOf(key, value);

  156. evictionCount++;

  157. }

  158. entryRemoved(true, key, value, null);

  159. }

  160. }

  161. /**

  162. * Removes the entry for {@code key} if it exists.

  163. * 删除key相应的cache项,返回相应的value

  164. * @return the previous value mapped by {@code key}.

  165. */

  166. public final V remove(K key) {

  167. if (key == null) {

  168. throw new NullPointerException(“key == null”);

  169. }

  170. V previous;

  171. synchronized (this) {

  172. previous = map.remove(key);

  173. if (previous != null) {

  174. size -= safeSizeOf(key, previous);

  175. }

  176. }

  177. if (previous != null) {

  178. entryRemoved(false, key, previous, null);

  179. }

  180. return previous;

  181. }

  182. /**

  183. * Called for entries that have been evicted or removed. This method is

  184. * invoked when a value is evicted to make space, removed by a call to

  185. * {@link #remove}, or replaced by a call to {@link #put}. The default

  186. * implementation does nothing.

  187. * 当item被回收或者删掉时调用。改方法当value被回收释放存储空间时被remove调用,

  188. * 或者替换item值时put调用,默认
    实现什么都没做。

  189. The method is called without synchronization: other threads may

  190. * access the cache while this method is executing.

  191. *

  192. * @param evicted true if the entry is being removed to make space, false

  193. *     if the removal was caused by a {@link #put} or {@link #remove}.

  194. * true—为释放空间被删除;false—put或remove导致

  195. * @param newValue the new value for {@code key}, if it exists. If non-null,

  196. *     this removal was caused by a {@link #put}. Otherwise it was caused by

  197. *     an eviction or a {@link #remove}.

  198. */

  199. protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {}

  200. /**

  201. * Called after a cache miss to compute a value for the corresponding key.

  202. * Returns the computed value or null if no value can be computed. The

  203. * default implementation returns null.

  204. * 当某Item丢失时会调用到,返回计算的相应的value或者null

  205. The method is called without synchronization: other threads may

  206. * access the cache while this method is executing.

  207. *

  208. If a value for {@code key} exists in the cache when this method

  209. * returns, the created value will be released with {@link #entryRemoved}

  210. * and discarded. This can occur when multiple threads request the same key

  211. * at the same time (causing multiple values to be created), or when one

  212. * thread calls {@link #put} while another is creating a value for the same

  213. * key.

  214. */

  215. protected V create(K key) {

  216. return null;

  217. }

  218. private int safeSizeOf(K key, V value) {

  219. int result = sizeOf(key, value);

  220. if (result < 0) {

  221. throw new IllegalStateException("Negative size: " + key + “=” + value);

  222. }

  223. return result;

  224. }

  225. /**

  226. * Returns the size of the entry for {@code key} and {@code value} in

  227. * user-defined units.  The default implementation returns 1 so that size

  228. * is the number of entries and max size is the maximum number of entries.

  229. * 返回用户定义的item的大小,默认返回1代表item的数量,最大size就是最大item值

  230. An entry’s size must not change while it is in the cache.

  231. */

  232. protected int sizeOf(K key, V value) {

  233. return 1;

  234. }

  235. /**

  236. * Clear the cache, calling {@link #entryRemoved} on each removed entry.

最后

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取
0.      */

  1. protected int sizeOf(K key, V value) {

  2. return 1;

  3. }

  4. /**

  5. * Clear the cache, calling {@link #entryRemoved} on each removed entry.

最后

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

[外链图片转存中…(img-7R2o989d-1718991877996)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/731805.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CVPR最佳论文:谷歌基于Spectral Volume从单图生成视频

一、摘要&#xff1a; 论文&#xff1a;Generative Image Dynamics&#xff0c;https://arxiv.org/pdf/2309.07906 项目主页&#xff1a;https://generative-dynamics.github.io/ 本文提出了一种新颖的方法来模拟场景运动的图像空间先验。通过从真实视频序列中提取的自然振荡…

调试实战 | 记一次有教益的 vs2022 内存分配失败崩溃分析(续)

前言 前一阵子遇到了 vs2022 卡死的问题&#xff0c;在上一篇文章中重点分析了崩溃的原因 —— 当 vs2022 尝试分配 923MB 的内存时&#xff0c;物理内存页文件大小不足以满足这次分配请求&#xff0c;于是抛出异常。 本篇文章将重点挖掘一下 vs2022 在崩溃之前已经分配的内容…

昇思25天学习打卡营第4天|网络构建|函数式自动微分

学AI还能赢奖品&#xff1f;每天30分钟&#xff0c;25天打通AI任督二脉 (qq.com) 网络构建 神经网络模型是由神经网络层和Tensor操作构成的&#xff0c;mindspore.nn提供了常见神经网络层的实现&#xff0c;在MindSpore中&#xff0c;Cell类是构建所有网络的基类&#xff0c;也…

借助AI营销类API,实现自动化的营销流程

借助AI营销类API&#xff0c;企业可以实现自动化的营销流程&#xff0c;提高效率和效果&#xff0c;并节省大量的时间和资源。这些API利用人工智能和机器学习的技术&#xff0c;能够自动化地执行各种营销任务和流程。首先&#xff0c;AI营销类API可以帮助企业实现自动化的市场调…

【鸿蒙】创建第⼀个鸿蒙项⽬

点击 Create Project 配置项目 开发工具界面 工程介绍

探索AI前沿:本地部署GPT-4o,打造专属智能助手!

目录 1、获取API_key 2、开始调用 3、openai连接异常 4、解决方法&#xff1a; 5、调用GPT-4o 1、获取API_key 这里就不多赘述了&#xff0c;大家可以参考下面这篇博客 怎么获取OpenAI的api-key【人工智能】https://blog.csdn.net/qq_51625007/article/details/13763274…

大数据与java哪个好找工作?这篇文章帮你做选择!

大数据与java哪个好找工作&#xff1f;这篇文章帮你做选择&#xff01; 还在为选择Java开发还是Java大数据而头疼吗&#xff1f;别担心&#xff0c;本文将从就业前景、学习方向、学习内容以及薪资待遇四个方面&#xff0c;为你揭开Java和Java大数据的神秘面纱&#xff0c;帮你做…

ZW3D二次开发_删除草图中的实体

1.目前草图中的实体不能直接通过id删除&#xff0c;而是通过entityPath实体路径&#xff0c;所以需要将id转化为实体路径。 2.以下示例代码的主要功能为获取草图中的所有实体并删除&#xff1a; int Count;int *idEnts;ZF_CALL(cvxSkInqGeom(&Count, &idEnts));//获取…

《窄门》情不知所起,而一往情深

《窄门》情不知所起&#xff0c;而一往情深 安德烈纪德&#xff08;1869-1951&#xff09;&#xff0c;法国作家。纪德一生著有小说、剧本、论文、散文、日记、书信多种&#xff0c;主要作品有小说《背德者》《窄门》《田园交响曲》《伪币制造者》等&#xff0c;戏剧《康多尔王…

x64汇编fastcall调用约定

x64汇编环境&#xff1a;只需要在x86基础上对项目属性进行设置&#xff0c;将平台设置为所有平台&#xff1b; 以及在将debug改为x64模式即可&#xff1a; 后续写完代码直接生成项目再使用本地调试器进行运行即可。 fastcall调用约定 在x64架构下&#xff0c;fastcall调用约定…

android倒计时封装(活动进入后台,倒计时依然能正常计时)

public class TimeUtils { /倒计时时长 单位&#xff1a;秒/ public static int COUNT 20*60; /当前做/ private static int CURR_COUNT 0; /预计结束的时间/ private static long TIME_END 0; /计时器/ private static Timer countdownTimer; /显示倒计时的textVi…

大数据学习-大数据介绍

意义 从海量的数据中分析出海量数据背后的价值 需要分析海量的数据&#xff0c;就需要存储、计算和分析 那就需要分布式多台计算机合适的工具来处理数据 工具 特点 大数据的核心工作&#xff1a;从海量的、高增长的、多类别的、信息密度低的数据中挖掘出高质量的结果 数据存储…

STM32通过SPI软件读写W25Q64

文章目录 1. W25Q64 2. 硬件电路 3. W25Q64框架图 4. 软件/硬件波形对比 5. 代码实现 5.1 MyI2C.c 5.2 MyI2C.h 5.3 W25Q64.c 5.4 W25Q64.h 5.5 W25Q64_Ins.h 5.6 main.c 1. W25Q64 对于SPI通信和W25Q64的详细解析可以看下面这篇文章 STM32单片机SPI通信详解-CSDN博…

开发中遇到的一个bug

遇到的报错信息是这样的&#xff1a; java: Annotation processing is not supported for module cycles. Please ensure that all modules from cycle [hm-api,hm-common,hm-service] are excluded from annotation processing 翻译过来就是存在循环引用的情况&#xff0c;导…

C++进阶之AVL树

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言进阶 数据结构初阶 Linux C初阶 C进阶​ ​​​​算法 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂 目录 一.前言 二.插入 三.旋转 3.1右旋 …

postman国内外竞争者及使用详解分析

一、postman简介 Postman 是一款广泛使用的 API 开发和测试工具&#xff0c;适用于开发人员和测试人员。它提供了一个直观的界面&#xff0c;用于发送 HTTP 请求、查看响应、创建和管理 API 测试用例&#xff0c;以及自动化 API 测试工作流程。以下是 Postman 的主要功能和特点…

Docker常用操作和命令

文章目录 1、卸载旧版本 2、yum安装Docker CE&#xff08;社区版&#xff09; 3、添加镜像加速器 4、docker --version 查看docker版本 5、docker info 或 docker system info 显示 Docker 系统的详细信息&#xff0c;包括容器、镜像、网络等 6、docker search 搜索镜像 …

JVM类加载器与双亲委派机制

通过上一篇Java的类加载机制相信大家已经搞明白了整个类加载从触发时机&#xff0c;接着我们就来看下类加载器&#xff0c;因为类加载机制是有加载器实现的。 类加载器的分类 启动类加载器 Bootstrap ClassLoader 是 Java 虚拟机&#xff08;JVM&#xff09;的一部分&#x…

C#调用OpenCvSharp实现图像的直方图均衡化

本文学习基于OpenCvSharp的直方图均衡化处理方式&#xff0c;并使用SkiaSharp绘制相关图形。直方图均衡化是一种图像处理方法&#xff0c;针对偏亮或偏暗的图像&#xff0c;通过调整图像的像素值来增强图像对比度&#xff0c;详细原理及介绍见参考文献1-4。   直方图均衡化第…

【中学教资科目二】02中学课程

02中学课程 第一节 课程概述1.1 课程的分类 第二节 课程组织2.1 课程内容的文本表现形式2.2 课程评价 第三节 基础教育课程改革3.1 基础教育改革的目标3.2 新课改的课程结构 第一节 课程概述 1.1 课程的分类 学校课程有多种类型&#xff0c;其中最利于学生系统掌握人类所取得的…