这里我将会给大家演示用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. 【CC评网】2013.第44周 把握每天的第一个小时

    [CC评网]2013.第44周 把握每天的第一个小时 更简单的格式 终于投入到markdown的怀抱.让博客的写作回归到内容本身,同时也能保证阅读的良好体验:如果有心情,写个js,提取h3 h2标题组 ...

  2. Protractor AngularJS测试框架教程

    Protractor是一个建立在WebDriverJS基础上的端到端(E2E)的AngularJS JavaScript Web应用程序测试框架.Protractor全自动化真实的模拟用户在真正的浏览 ...

  3. 你不知道的css中的expression

    expression是在IE5版本之后支持使用的,用来把CSS属性和Javascript脚本关联起来,[这里的CSS属性可以是元素固有的属性,也可以是自定义属性.]是动态设置CSS属性的强大方法,但也 ...

  4. CDN学习笔记一(CDN是什么?)

    CDN是什么? 谈到CDN的作用,可以用8年买火车票的经历来形象比喻: 8年前,还没有火车票代售点一说,12306.cn更是无从说起.那时候火车票还只能在火车站的售票大厅购买,而我所住的小县城并不通火 ...

  5. oracle学习之bulk collect用法

    通过bulk collect减少loop处理的开销,使用Bulk Collect提高Oracle查询效率 Oracle8i中首次引入了Bulk Collect特性,该特性可以让我们在PL/SQL中能使 ...

  6. linux 目录结构图解

    参考资料:http://www.linuxidc.com/Linux/2016-08/134701.htm

  7. poj2986A Triangle and a Circle&&poj3675Telescope(三角形剖分)

    链接 2986是3675的简化版,只有一个三角形. 这题主要在于求剖分后三角形与圆的相交面积,需要分情况讨论. 具体可以看此博客 http://hi.baidu.com/billdu/item/703 ...

  8. JS自总结

    1.js获得当前元素   event.srcElement:   获取当前父元素   event.srcElement.parentElement   var rowIndex = e.parentE ...

  9. Longest Common Prefix

    Description: Write a function to find the longest common prefix string amongst an array of strings.( ...

  10. android studio导入 so ,jar 文件。

    环境为: Android Studio 1.0.2 如果是jar文件的话,请直接拷贝jar文件到项目的libs文件夹下,然后运行:Sync Project with Gradle Files.如下图2 ...