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
<div class="post-tags">
<a href="/misc/goto?guid=5033828700170783920" rel="tag" title="cache (1 topics)" target="_blank">cache</a>, <a href="/misc/goto?guid=5033828700278959880" rel="tag" title="callable (1 topics)" target="_blank">callable</a>, <a href="/misc/goto?guid=5033828700383011820" rel="tag" title="guava (2 topics)" target="_blank">guava</a>, <a href="/misc/goto?guid=5033828700495349609" rel="tag" title="Java (42 topics)" target="_blank">Java</a> </div>
</div>
Google Guava v11 Collections示例
Jan 6th
<div class="post-content clearfix">
<p><a href="/misc/goto?guid=4958184190515616602" target="_blank" target="_blank">Guava</a> 中文是石榴的意思,該項目是 Google 的一個開源項目,包含許多 Google 核心的 Java 常用庫。目前主要包含:</p>
- 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 </ul>
這里先介紹一下最常用的com.google.common.collect包中的最常用的一些API,僅僅討論一下API的使用方法,沒有討論到實現細節。
1:Collections的構造方法
我們平時直接創建Collections對象的方法一般都是用new關鍵字,有泛型的情況下看起來會比較長:
Map<String , Map<String , String>> see = new HashMap<String, Map<String,String>>();
</div>在java7中,這個初始化做了簡化:
Map<String , Map<String , String>> see = new HashMap<>();
</div>可以通過Guava的API來這樣寫:
Map<String , Map<String , String>> see = Maps.newHashMap();
</div>得到一個有size的Map:
Map<String , Map<String , String>> see = Maps.newHashMapWithExpectedSize(32);
</div>在JDK的collection類型,在Guava中都可以找到相關的static的構造方法,例如:Lists , Sets , Maps , Queues。新的colleciont類型提供了直接構造的方法,例如:HashMultimap<String, String> multiMap = HashMultimap.create();
</div>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;
}
});
</div>把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";
}
});
</div>需要說明的是每次調用返回都是新的對象,同時操作過程不是線程安全的。
</div>
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());
}
</div>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
}
</div> </div>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}
}
</div> </div>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);
}
</div>Common-lang,spring中的方法需要逐個調用。而Guava中支持。
</div>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);
}
}
</div> </div>參考資料
http://blog.solidcraft.eu/2010/10/googole-guava-v07-examples.html
http://insightfullogic.com/blog/2011/oct/21/5-reasons-use-guava/#
http://codingjunkie.net/google-guava-cache/
</div> </div> </div> 轉自:http://www.longtask.com/blog/?tag=guava