--- layout: default title: Guava學習的一點東西 category: tech ---
{{ page.title }}
guava仍是很先進的,有些東西java8中才會有的,guava中早就應用了,好比Lists.newXXXX; guava中fluent格式,讓我以爲不習慣,雖然的確是省了不少單詞。 做爲一個工具,最須要知道怎麼用。是否是好用,只有用了才知道。因此我就用了下,見下面的代碼了 其實寫的都是測試用例;註釋裏面有一些介紹說明; {% highlight java %} //guava中的新集合類: public class GuavaNewCollections { /** * 2個很好的教程 * http://www.ibm.com/developerworks/cn/java/j-lo-googlecollection/#ibm-pcon * http://ifeve.com/google-guava-newcollectiontypes/ */ private static Logger log = Logger.getLogger(GuavaNewCollections.class); static final String[] testString = new String[] { "a", "b", "c", "a", "a", "b" }; @Test public void newGuavaCollections() { String test = null; log.debug(Objects.equal(test, "ab"));// 用Objects能夠不用判斷對象是否爲空。 ObjectsCase oc = new ObjectsCase(); oc.setParam(123); System.out.println(oc.toString());// guava帶的toString工具類 /**** * * multi,能夠用來計數,某個字符串出現了多少次等等; * * ******************/ Multiset
multiSet = HashMultiset.create(); Multiset
multiSet2 = TreeMultiset.create(); Multiset
multiSet4 = LinkedHashMultiset.create(); Multiset
multiSet3 = ConcurrentHashMultiset.create(); multiSet.addAll(Arrays.asList(testString)); multiSet.add("a", 3); multiSet.add("d", 4); multiSet.remove("a", 8);// 減小計數; for (String s : multiSet.elementSet()) { log.debug(s + " count:" + multiSet.count(s)); } /**********************/ /***** * multiMap 一個key能夠對應多個value; * ListMultimap.get(key)返回List,SetMultimap.get(key)返回Set。 * * Muitimap 接口的主要實現類有: HashMultimap: key 放在 HashMap,而 value 放在 * HashSet,即一個 key 對應的 value 不可重複 ArrayListMultimap: key 放在 HashMap,而 * value 放在 ArrayList,即一個 key 對應的 value 有順序可重複 LinkedHashMultimap: key * 放在 LinkedHashMap,而 value 放在 LinkedHashSet,即一個 key 對應的 value 有順序不可重複 * TreeMultimap: key 放在 TreeMap,而 value 放在 TreeSet,即一個 key 對應的 value * 有排列順序 ImmutableMultimap: 不可修改的 Multimap */ Multimap
myMultimap = ArrayListMultimap.create(); for (String t : testString) { myMultimap.put(t, t + "-v"); } log.debug("myMultimap size:" + myMultimap.size()); log.debug(myMultimap.get("a")); log.debug(myMultimap.get("b")); log.debug(myMultimap.get("d")); for (String v : myMultimap.values()) { log.debug(v); } Collection
vl = myMultimap.get("a");// 返回Collection HashMultimap.create(); /** * BiMap 實現了 java.util.Map 接口。它的特色是它的 value 和它 key 同樣也是不可重複的,換句話說它的 key * 和 value 是等價的。若是你往 BiMap 的 value 裏面放了重複的元素,就會獲得 * IllegalArgumentException。 BiMap的經常使用實現有: HashBiMap: key 集合與 value 集合都有 * HashMap 實現 EnumBiMap: key 與 value 都必須是 enum 類型 ImmutableBiMap: 不可修改的 * BiMap */ BiMap
biMap = HashBiMap.create(); for (String t : testString) { biMap.put(t, t + "-v"); } log.debug("bimap get a-v:" + biMap.inverse().get("a-v")); /** * 當你想使用多個鍵作索引的時候,你可能會用相似Map
> * 的實現,這種方式很醜陋,使用上也不友好。Guava爲此提供了新集合類型Table,它有兩個支持全部類型的鍵:」行」和」列」 * HashBasedTable:本質上用HashMap
>實現; * TreeBasedTable:本質上用TreeMap
>實現; * ImmutableTable:本質上用ImmutableMap
>實現;注:ImmutableTable對稀疏或密集的數據集都有優化。 * ArrayTable:要求在構造時就指定行和列的大小,本質上由一個二維數組實現 * ,以提高訪問速度和密集Table的內存利用率。ArrayTable與其餘Table的工做原理有點不一樣,請參見Javadoc瞭解詳情。 */ Table
weightedGraph = HashBasedTable.create(); weightedGraph.put(1, 1, 4); weightedGraph.put(2, 2, 20); weightedGraph.put(2, 3, 23); weightedGraph.put(3, 3, 5); Map
row2 = weightedGraph.row(2); // returns a Map // mapping v2 to 4, // v3 to 20 log.debug("row2 ,3:" + row2.get(3)); log.debug("colum 3 3:" + weightedGraph.column(3).get(3)); // returns a // Map // mapping // v1 to 20, // v2 to 5 /** * RangeSet,挺有意思,和數學裏的集合定義更接近了; * RangeSet描述了一組不相連的、非空的區間。當把一個區間添加到可變的RangeSet時,全部相連的區間會被合併,空區間會被忽略。 * 注:RangeSet不支持GWT,也不支持JDK5和更早版本;由於,RangeSet須要充分利用JDK6中NavigableMap的特性。 */ RangeSet
rangeSet = TreeRangeSet.create(); rangeSet.add(Range.closed(1, 10)); // {[1,10]} rangeSet.add(Range.closedOpen(11, 15));// 添加[11,15],獲得不相連區間:{[1,10], // [11,15)} rangeSet.add(Range.closedOpen(15, 20)); // 添加[15,20],相連區間; {[1,10], // [11,20)} rangeSet.add(Range.openClosed(0, 0)); // 空區間; {[1,10], [11,20)} rangeSet.remove(Range.open(5, 10)); // 分割[1, 10]; {[1,5], [10,10], // [11,20)} /** * RangeMap * RangeMap描述了"不相交的、非空的區間"到特定值的映射。和RangeSet不一樣,RangeMap不會合並相鄰的映射, * 即使相鄰的區間映射到相同的值。 */ RangeMap
rangeMap = TreeRangeMap.create(); rangeMap.put(Range.closed(1, 10), "foo"); // {[1,10] => "foo"} rangeMap.put(Range.open(3, 6), "bar"); // {[1,3] => "foo", (3,6) => // "bar", [6,10] => "foo"} rangeMap.put(Range.open(10, 20), "foo"); // {[1,3] => "foo", (3,6) => // "bar", [6,10] => "foo", // (10,20) => "foo"} rangeMap.remove(Range.closed(5, 11)); // {[1,3] => "foo", (3,5) => // "bar", (11,20) => "foo"} } } {% endhighlight %} {% highlight java %} //guava集合中的新方法 public class GuavaCollectionsUtils { /** * http://ifeve.com/google-guava-collectionutilities/ * 提供java.util.Collections中沒有的集合工具 */ @Test public void test() { /** * jdk提供的建立集合 List
list = new * ArrayList
(); */ // guava提供的建立集合的方式 List
list = Lists.newArrayList(); Map
map = Maps.newLinkedHashMap(); List
theseElements = Lists.newArrayList("alpha", "beta", "gamma"); Set
createSet = Sets.newHashSet("ste", "haha"); /** * 原本覺得expectedSize或者Capacity是限定長度的,其實沒有,只是限定初始化的長度; */ List
exactly100 = Lists.newArrayListWithCapacity(100); List
approx100 = Lists.newArrayListWithExpectedSize(100); Set
approx100Set = Sets.newHashSetWithExpectedSize(100); for (int i = 0; i < 111; i++) { exactly100.add(i + ""); approx100.add(i + ""); approx100Set.add(i + ""); } for (String a : exactly100) { System.out.print(a + ","); } System.out.println(); for (String a : approx100) { System.out.print(a + ","); } System.out.println(); List
ss = Lists.newArrayList(approx100Set); /** * 和java裏帶的Collection是兼容的 */ Collections.sort(ss); for (String a : ss) { System.out.print(a + ","); } System.out.println(); /** * immutable意思是不可變的;下面這幾個Immutable開頭的集合都是不可變的。在初始化的時候就肯定了裏面的內容,不會變了。 * sets的帶的方法也不錯 ,求交集intersection返回的是一個SetView,並集是用union,意思也更準確 * jdk裏帶的是set.retainAll(c)修改了set內容; */ Set
wordsWithPrimeLength = ImmutableSet.of("one", "two", "three", "six", "seven", "eight"); Set
primes = ImmutableSet.of("two", "three", "five", "seven"); SetView
intersection = Sets.intersection(primes, wordsWithPrimeLength);// 交集 // intersection包含"two", "three", "seven" for (String s : intersection) { System.out.print(s + ","); } System.out.println(); SetView
view = Sets.union(primes, wordsWithPrimeLength);// 並集 for (String s : view) { System.out.print(s + ","); } System.out.println(); } } {% endhighlight %} {% highlight java %} //guava中的緩存,說實話,我的感受很差用。 package com.miracle.guava; public class GuavaCache { @Test public void TestLoadingCache() throws Exception { /** * * http://ifeve.com/google-guava-cachesexplained/ * * 一般來講,Guava Cache適用於: * * 你願意消耗一些內存空間來提高速度。 你預料到某些鍵會被查詢一次以上。 緩存中存放的數據總量不會超出內存容量。(Guava * Cache是單個應用運行時的本地緩存。它不把數據存放到文件或外部服務器。若是這不符合你的需求,請嘗試Memcached這類工具) * 若是你的場景符合上述的每一條,Guava Cache就適合你。 * * 如同範例代碼展現的同樣,Cache實例經過CacheBuilder生成器模式獲取,可是自定義你的緩存纔是最有趣的部分。 * * 注:若是你不須要Cache中的特性,使用ConcurrentHashMap有更好的內存效率—— * 但Cache的大多數特性都很難基於舊有的ConcurrentMap複製,甚至根本不可能作到。 * * */ LoadingCache
cahceBuilder = CacheBuilder.newBuilder().build(new CacheLoader
() { @Override public String load(String key) throws Exception { String strProValue = "hello " + key + "!"; return strProValue; } }); System.out.println("jerry value:" + cahceBuilder.apply("jerry")); System.out.println("jerry value:" + cahceBuilder.get("jerry")); System.out.println("peida value:" + cahceBuilder.get("peida")); System.out.println("lisa value:" + cahceBuilder.apply("lisa")); cahceBuilder.put("harry", "ssdded"); System.out.println("harry value:" + cahceBuilder.get("harry")); /** * 一個殘酷的現實是,咱們幾乎必定沒有足夠的內存緩存全部數據。你你必須決定:何時某個緩存項就不值得保留了?Guava * Cache提供了三種基本的緩存回收方式:基於容量回收、定時回收和基於引用回收 */ LoadingCache
cacheBuilder2 = CacheBuilder.newBuilder().maximumSize(2).expireAfterWrite(1, TimeUnit.SECONDS) .build(new CacheLoader
() { @Override public String load(String key) throws Exception { String strProValue = "go " + key + "!"; return strProValue; } }); cacheBuilder2.put("beijing", "go beijing!"); /** * 若是你要的數據,緩存中沒有,能夠調用一個Callable來生成。 */ System.out.println(cacheBuilder2.get("1")); System.out.println(cacheBuilder2.get("2")); System.out.println(cacheBuilder2.get("3")); System.out.println(cacheBuilder2.get("abc", new Callable
() { public String call() { return "I'm generated abc!"; } })); System.out.println(cacheBuilder2.get("beijing")); System.out.println(cacheBuilder2.get("abc")); TimeUnit.SECONDS.sleep(2); System.out.println(cacheBuilder2.get("1")); } @Test public void testcallableCache() throws Exception { Cache
cache = CacheBuilder.newBuilder().maximumSize(1000).build(); String resultVal = cache.get("jerry", new Callable
() { public String call() { String strProValue = "hello " + "jerry" + "!"; return strProValue; } }); System.out.println("jerry value : " + resultVal); resultVal = cache.get("peida", new Callable
() { public String call() { String strProValue = "hello " + "peida" + "!"; return strProValue; } }); System.out.println("peida value : " + resultVal); } } {% endhighlight %}
{{ page.date | date_to_string }}html