这里我将会给大家演示用ConcurrentHashMap类和lambda表达式实现一个本地缓存。因为Map有一个新的方法可以在key为Null的时候自动计算一个新的value值。非常完美的实现cache。来看下代码:

public static void main(String[] args) {
for (int i = 0; i < 10; i++)
System.out.println(
"f(" + i + ") = " + fibonacci(i));
} static int fibonacci(int i) {
if (i == 0)
return i; if (i == 1)
return 1; System.out.println("Calculating f(" + i + ")");
return fibonacci(i - 2) + fibonacci(i - 1);
}

当然,这种方式很傻瓜了。即使对于一个非常小的数,例如fibonacci(5),上面的代码打印出很多行,而且都是在进行重复计算,输出如下(只截取一部分):

Calculating f(6)
Calculating f(4)
Calculating f(2)
Calculating f(3)
Calculating f(2)
Calculating f(5)
Calculating f(3)
Calculating f(2)
Calculating f(4)
Calculating f(2)
Calculating f(3)
Calculating f(2)
f(6) = 8

我们想要做的就是创建一个缓存,用来计算斐波那契数列。最直接的方法就是在缓存中存放所有的value值。cache的创建如下:

static Map<Integer, Integer> cache = new ConcurrentHashMap<>();

(译者注:这种写法在Java8中是允许的)

声明cache之后,通过Map.computeIfAbsent() 方法,可以在key所对应的value值不存在的情况下,计算一个新的value值。超高速缓存(Caching)!由于这个方法是自动执行的,而且我们使用了 ConcurrentHashMap对象,这个缓存是线程安全的,不需要手动的去写同步方法。另外,它不仅仅可以处理斐波那契额数列,在其他地方也可以被重复使用。

不过现在,我们看看如何在fibonacci()方法中使用缓存。

static int fibonacci(int i) {
if (i == 0)
return i; if (i == 1)
return 1; return cache.computeIfAbsent(i, (key) ->
fibonacci(i - 2)
+ fibonacci(i - 1));
}

瞧瞧。不能比这个再简单了吧。想要证明吗?好吧,每当我们计算一个新值的时候,都在控制台输出信息:

static int fibonacci(int i) {
if (i == 0)
return i; if (i == 1)
return 1; return cache.computeIfAbsent(i, (key) -> {
System.out.println(
"Slow calculation of " + key); return fibonacci(i - 2) + fibonacci(i - 1);
});
}

程序输出如下:

f(0) = 0
f(1) = 1
Slow calculation of 2
f(2) = 1
Slow calculation of 3
f(3) = 2
Slow calculation of 4
f(4) = 3
Slow calculation of 5
f(5) = 5
Slow calculation of 6
f(6) = 8
Slow calculation of 7
f(7) = 13
Slow calculation of 8
f(8) = 21
Slow calculation of 9
f(9) = 34

在Java7下又如何实现呢?

这样代码就会多一些,我们可以使用double-checked locking来实现:

static int fibonacciJava7(int i) {
if (i == 0)
return i; if (i == 1)
return 1; Integer result = cache.get(i);
if (result == null) {
synchronized (cache) {
result = cache.get(i); if (result == null) {
System.out.println(
"Slow calculation of " + i); result = fibonacci(i - 2)
+ fibonacci(i - 1);
cache.put(i, result);
}
}
} return result;
}

注:你实际的解决方案很可能会用到Guava Caches。

总结:Lambdas 表达式是Java8中非常重要的一部分。我们不要忘记添加到库中的所有的新特性。

原文链接: Jooq 翻译: ImportNew.com - 宋 涛
译文链接: http://www.importnew.com/10227.html

-----------------------分割线--------------------------------------------------

目前Oracle官方还未放出JDK1.8 的 Documentation ,查看API可以访问URL:http://download.java.net/jdk8/docs/api/

[转]Java8-本地缓存的更多相关文章

  1. Java8简单的本地缓存实现

    原文出处:lukaseder         Java8简单的本地缓存实现 这里我将会给大家演示用ConcurrentHashMap类和lambda表达式实现一个本地缓存.因为Map有一个新的方法,在 ...

  2. 使用Guava cache构建本地缓存

    前言 最近在一个项目中需要用到本地缓存,在网上调研后,发现谷歌的Guva提供的cache模块非常的不错.简单易上手的api:灵活强大的功能,再加上谷歌这块金字招牌,让我毫不犹豫的选择了它.仅以此博客记 ...

  3. 本地缓存解决方案-Caffeine Cache

    1.1 关于Caffeine Cache ​ Google Guava Cache是一种非常优秀本地缓存解决方案,提供了基于容量,时间和引用的缓存回收方式.基于容量的方式内部实现采用LRU算法,基于引 ...

  4. HTML5权威指南--Web Storage,本地数据库,本地缓存API,Web Sockets API,Geolocation API(简要学习笔记二)

    1.Web Storage HTML5除了Canvas元素之外,还有一个非常重要的功能那就是客户端本地保存数据的Web Storage功能. 以前都是用cookies保存用户名等简单信息.   但是c ...

  5. 微信小程序之本地缓存(十)

    [未经作者本人同意,请勿以任何形式转载] 目前,微信给每个小程序提供了10M的本地缓存空间(哎哟妈呀好大) 有了本地缓存,你的小程序可以做到: 离线应用(已测试在无网络的情况下,可以操作缓存数据) 流 ...

  6. HTML5本地缓存数据

    //HTML5本地缓存数据 function putObj(key, data) { if (!!window.localStorage) { var obj = { "key": ...

  7. iOS //清除本地缓存

    //清除本地缓存 -(void)clearCache{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT ...

  8. Java学习之ConcurrentHashMap实现一个本地缓存

    ConcurrentHashMap融合了Hashtable和HashMap二者的优势. Hashtable是做了线程同步,HashMap未考虑同步.所以HashMap在单线程下效率较高,Hashtab ...

  9. iOS五种本地缓存数据方式

    iOS五种本地缓存数据方式   iOS本地缓存数据方式有五种:前言 1.直接写文件方式:可以存储的对象有NSString.NSArray.NSDictionary.NSData.NSNumber,数据 ...

  10. OutputCache 如何使用本地缓存 【转】

    注意!ASP.NET MVC 3 的一个 OutputCache 问题   在用 ASP.NET MVC 3 重写博客园网站首页时,特地留意了一下这个缓存问题,通过这篇博文分享一下. 在 ASP.NE ...

随机推荐

  1. Nginx基础知识之——配置文件信息(检查配置文件是否正确)

    一.检查配置文件是否正确: /usr/local/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf 检查结果: nginx: [emerg] ngin ...

  2. OpenERP QWeb模板标签笔记

    在OpenERP中,通过QWeb来对模板进行渲染后加载到浏览器中,而模板中有许多的标签来定制各种需求变化,在这里记录学习过程中碰到的标签定义,以方便查询. 模板中的标签统一都是以"t-&qu ...

  3. 在代码中修改TextView的DrawableRight图片

    TextView的xml <TextView android:id="@+id/textciew1" android:layout_width="match_par ...

  4. Mysql的最佳优化经验20多条

    原文:http://blog.csdn.net/lifuxiangcaohui/article/details/6207801 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其 ...

  5. scala集合

    优先使用不可变集合.不可变集合适用于大多数情况,让程序易于理解和推断,因为它们是引用透明的( referentially transparent )因此缺省也是线程安全的. 使用可变集合时,明确地引用 ...

  6. LTIB常用命令3

    http://blog.csdn.net/junht/article/details/7656540 LTIB 中的包 4.3.1  查看哪些包是使能的,并且可以安装 在配置ltib之前,您可以在一个 ...

  7. K均值聚类(Kmeans)

    Sigma = [1, 0; 0, 1]; mu1 = [1, -1]; x1 = mvnrnd(mu1, Sigma, 200); mu2 = [5.5, -4.5]; x2 = mvnrnd(mu ...

  8. 程序猿必知会的JavaScript 的遍历方式

    不管是移动移动端开发还是web端开发,我们对JS的使用频率都在增加,今天小编将要和大家分享的就是JavaScript中,遍历方式的一些实现方法,个人感觉还是很有用的,有兴趣的童鞋可以一起来看看. 为了 ...

  9. ionic 原生日历控件不支持,改用 datepicker-for-ionic

    具体参考地址 http://npm.taobao.org/package/datepicker-for-ionic

  10. android widget 点击进入应用

    package com.ljapps.wifix.ui.provider; import android.app.PendingIntent; import android.appwidget.App ...