Google Guava V11 中的Cache操作
Google Guava cache的主要功能点:
* 你需要给现有系统加速;
* 有些key需要不知一次的查询获取;
* 从策略上讲,你的应用需要从策略上把所有的value从cache中清理出来 — 你试图减少重复的工作;[注:weakKey , weakValue]
* cache仅仅存储在内存中,没有在文件中或者其他的server上面,如果不满足你的需求,可以考虑Memcached
API的两种调用方式
1:普通的调用方式,通过key得到value的时间较短
2:延迟加载的处理方式,通过key得到value的时间较长
回收的参数设置
1. 大小的设置:CacheBuilder.maximumSize(long) CacheBuilder.weigher(Weigher) CacheBuilder.maxumumWeigher(long)
2. 时间:expireAfterAccess(long, TimeUnit) expireAfterWrite(long, TimeUnit)
3. 引用:CacheBuilder.weakKeys() CacheBuilder.weakValues() CacheBuilder.softValues()
4. 明确的删除:invalidate(key) invalidateAll(keys) invalidateAll()
5. 删除监听器:CacheBuilder.removalListener(RemovalListener)
refresh机制
1. LoadingCache.refresh(K) 在生成新的value的时候,旧的value依然会被使用。
2. CacheLoader.reload(K, V) 生成新的value过程中允许使用旧的value
3. CacheBuilder.refreshAfterWrite(long, TimeUnit) 自动刷新cache
未来要实现的功能
1. 更多统计信息,通过Cache.stats()来获取统计类CacheStats,例如缓存命中率,缓存获取实践统计等
2. asMap,把缓存动作一个ConcurrentMap
参考资料 :http://code.google.com/p/guava-libraries/wiki/CachesExplained#Inserted_Directly
Google Guava v11 Collections示例
Jan 6th
Guava 中文是石榴的意思,该项目是 Google 的一个开源项目,包含许多 Google 核心的 Java 常用库。目前主要包含:
- com.google.common.annotations
- com.google.common.base
- com.google.common.cache
- com.google.common.collect
- com.google.common.eventbus
- com.google.common.io
- com.google.common.net
- com.google.common.primitives
- com.google.common.util.concurrent
这里先介绍一下最常用的com.google.common.collect包中的最常用的一些API,仅仅讨论一下API的使用方法,没有讨论到实现细节。
1:Collections的构造方法
我们平时直接创建Collections对象的方法一般都是用new关键字,有泛型的情况下看起来会比较长:
Map<String , Map<String , String>> see = new HashMap<String, Map<String,String>>();
在java7中,这个初始化做了简化:
Map<String , Map<String , String>> see = new HashMap<>();
可以通过Guava的API来这样写:
Map<String , Map<String , String>> see = Maps.newHashMap();
得到一个有size的Map:
Map<String , Map<String , String>> see = Maps.newHashMapWithExpectedSize(32);
在JDK的collection类型,在Guava中都可以找到相关的static的构造方法,例如:Lists , Sets , Maps , Queues。新的colleciont类型提供了直接构造的方法,例如:HashMultimap<String, String> multiMap = HashMultimap.create();
2:有限功能的函数式编程
介绍2个重要的接口:
com.google.common.base.Function : 根据输入值来得到输出值
com.google.common.base.Predicate : 根据输入值得到 true 或者 false
拿Collections2中有2个函数式编程的接口:filter , transform ,例如 :在Collection<Integer>中过滤大于某数的内容:
Collection<Integer> filterList = Collections2.filter(collections
, new Predicate<Integer>(){
@Override
public boolean apply(Integer input) {
if(input > 4)
return false;
else
return true;
}
});
把Lis<Integer>中的Integer类型转换为String , 并添加test作为后缀字符:
List<String> c2 = Lists.transform(list, new Function<Integer , String>(){
@Override
public String apply(Integer input) {
return String.valueOf(input) + "test";
}
});
需要说明的是每次调用返回都是新的对象,同时操作过程不是线程安全的。
3:Multimap and BiMap
Map中一个key只能有一个,后续put进去的内容会覆盖前面的内容,有些业务需要有相同的key,但是有不同的内容,Guava中提供了
Multimaps 来解决这个问题。
Multimap<String, String> prosons = HashMultimap.create();
prosons.put("longhao", "hubei");
prosons.put("lilei" , "henan");
prosons.put("longhao", "shanxi");
prosons.put("liuxia", "beijing");
prosons.put("lilei", "hainan");
Iterator<String> it = prosons.get("longhao").iterator();
while(it.hasNext()){
System.out.println(it.next());
}
BiMap可以有相同的key,但是不能有相同的value,如果不同的key设置了相同的value,则会抛出IllegalArgumentException异常,可以通过inverse()来反转kv,values()来获取value的set。
public void biMapShouldOnlyHaveUniqueValues() {
BiMap<Integer, String> biMap = HashBiMap.create();
biMap.put(1, "a");
biMap.put(2, "b");
biMap.put(3, "a"); //argh! an exception
}
4:tables
给出一个columns, rows , values, 这个API和Map<K , Map<K , V>>形式差不多,多了一些封装。例子:
static void tables(){
Table<Integer , String , Integer> user = HashBasedTable.create();
user.put(1, "longhao", 29);
user.put(1, "shuaige", 29);
user.put(2, "xiaomi", 1);
user.put(3, "soso", 3);
System.out.println(user.containsColumn("soso"));//true
System.out.println(user.containsColumn("3"));//false
System.out.println(user.contains(1, "xiaomi"));//false
System.out.println(user.contains(1, "meinv"));//true
System.out.println(user.row(1));//{shuaige=29, longhao=29}
}
5:更简洁的判断
使用Preconditions中的方法来判断是否为空等操作,这个操作和spring,apache common-lang中的API类似
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
static void checkParam(String name , Integer passwd){
checkNotNull(name , passwd);
checkArgument("" != name , passwd > 0);
}
Common-lang,spring中的方法需要逐个调用。而Guava中支持。
6:约束
对Collection中的新加入元素做约束,只有符合条件的元素才能够被添加到Collection中,可以使用Constraint类来操作。
示例代码:
import static com.google.common.collect.Constraints.constrainedList;
static void constraintExam(){
Constraint<String> chkListStr = new Constraint<String>(){
@Override
public String checkElement(String element) {
if(element.startsWith("h")){
throw new IllegalArgumentException("不允许有h开头的内容");
}
return element;
}
};
List<String> list = Lists.newArrayList("li","hao","a");
List<String> conList = constrainedList(list, chkListStr);
conList.add("soso");
conList.add("hqb");// throw IllegalArgumentException
for(String str : list){
System.out.println(str);
}
}
参考资料