正文java
Guava 對JDK集合的拓展,是最成熟且最受歡迎的部分。本文屬於Guava的核心,須要仔細看。編程
用不變的集合進行防護性編程和性能提高。工具
1 package guava.collect; 2 3 import com.google.common.collect.ImmutableSet; 4 5 /** 6 * @author denny 7 * @Description 不可變集合 8 * @date 2018/7/26 下午3:16 9 */ 10 public class ImmutableCollectionsTest { 11 /** 12 * 1.直接申明靜態集合 13 */ 14 public static final ImmutableSet<String> COLOR_NAMES_1 = ImmutableSet.of( 15 "red", 16 "orange", 17 "yellow", 18 "green"); 19 /** 20 * 2.防護式copy 21 */ 22 public static final ImmutableSet<String> COLOR_NAMES_2 = ImmutableSet.copyOf(COLOR_NAMES_1); 23 24 /** 25 * 3.builder建造者模式 26 */ 27 public static final ImmutableSet<String> COLOR_NAMES_3 = ImmutableSet.<String>builder().addAll(COLOR_NAMES_2).add("blue").build(); 28 29 30 public static void main(String[] args) { 31 System.out.println("of:"+COLOR_NAMES_1); 32 System.out.println("防護式copy:"+COLOR_NAMES_2); 33 System.out.println("建造者模式:"+COLOR_NAMES_3); 34 System.out.println("轉換成list:"+COLOR_NAMES_3.asList()); 35 } 36 }
打印:性能
of:[red, orange, yellow, green] 防護式copy:[red, orange, yellow, green] 建造者模式:[red, orange, yellow, green, blue] 轉換成list:[red, orange, yellow, green, blue]
提供multisets, multimaps, tables, bidirectional maps等,方便各類使用場景。測試
不少類,咱們只舉例分析multiset、multimap接口,其它的就在測試類中體現。ui
繼承自JDK:java.util.Collection接口,支持屢次添加相同的元素,且無序。google
當把Multiset當作普通的Collection時,它表現得就像無序的ArrayList:spa
當把Multiset看做Map<E, Integer>時,它也提供了符合性能指望的查詢操做:日誌
各類multimap實現類以下:blog
測試類以下:
1 package guava.collect; 2 3 import com.google.common.collect.BiMap; 4 import com.google.common.collect.ClassToInstanceMap; 5 import com.google.common.collect.HashBasedTable; 6 import com.google.common.collect.HashBiMap; 7 import com.google.common.collect.HashMultimap; 8 import com.google.common.collect.HashMultiset; 9 import com.google.common.collect.Lists; 10 import com.google.common.collect.Multimap; 11 import com.google.common.collect.Multiset; 12 import com.google.common.collect.MutableClassToInstanceMap; 13 import com.google.common.collect.Range; 14 import com.google.common.collect.RangeMap; 15 import com.google.common.collect.RangeSet; 16 import com.google.common.collect.Table; 17 import com.google.common.collect.TreeRangeMap; 18 import com.google.common.collect.TreeRangeSet; 19 20 /** 21 * @author denny 22 * @Description 多重集合測試類 23 * @date 2018/7/26 下午6:29 24 */ 25 public class MultiCollectionsTest { 26 public static void main(String[] args) { 27 28 System.out.println("====1.Multiset======="); 29 /** 1.Multiset 專用於統計元素出現次數 */ 30 Multiset<String> wordsMultiset = HashMultiset.create(); 31 // 添加元素 32 wordsMultiset.addAll(Lists.newArrayList("a", "b", "c", "a", "b", "a")); 33 //遍歷不一樣元素集合,打印次數 34 wordsMultiset.elementSet().forEach(e -> System.out.println(e + ":" + wordsMultiset.count(e))); 35 36 System.out.println("====2.Multimap======="); 37 /** 2.Multimap 1個key多value映射 */ 38 Multimap<String, Integer> multimap = HashMultimap.create(); 39 multimap.put("a", 1); 40 multimap.put("b", 2); 41 multimap.put("c", 3); 42 multimap.put("a", 4); 43 System.out.println("鍵-值集合映射:"); 44 // 鍵-值集合映射:asMap()轉成map(key,Collection<E>),再調用map相關方法,打印 45 multimap.asMap().entrySet().forEach(e -> System.out.println(e.getKey() + ":" + e.getValue())); 46 System.out.println("鍵-單個值映射:"); 47 // 鍵-單個值映射:包括重複鍵 48 multimap.entries().forEach(e -> System.out.println(e.getKey() + ":" + e.getValue())); 49 50 System.out.println("====3.BiMap======="); 51 /** 3.BiMap 鍵值反轉 */ 52 BiMap<String, Integer> biMap = HashBiMap.create(); 53 biMap.put("a", 1); 54 biMap.put("b", 2); 55 System.out.println("鍵值對" + biMap); 56 System.out.println("鍵值反轉:" + biMap.inverse()); 57 58 System.out.println("====4.Table======="); 59 /** 4.Table <R rowKey, C columnKey, V value> */ 60 Table<String, String, Integer> table = HashBasedTable.create(); 61 table.put("a", "b", 1); 62 table.put("a", "c", 2); 63 table.put("d", "b", 3); 64 System.out.println(table); 65 System.out.println("row a=" + table.row("a")); 66 System.out.println("column b=" + table.column("b")); 67 68 /** 5.ClassToInstanceMap 類、實例映射 */ 69 System.out.println("====5.ClassToInstanceMap======="); 70 ClassToInstanceMap<Number> classToInstanceMap = MutableClassToInstanceMap.create(); 71 classToInstanceMap.putInstance(Integer.class, 1); 72 classToInstanceMap.putInstance(Double.class, 2D); 73 classToInstanceMap.putInstance(Long.class, 3L); 74 System.out.println(classToInstanceMap); 75 76 /** 6. RangeSet 區間運算; RangeMap 區間映射*/ 77 System.out.println("====6.RangeSet、RangeMap======="); 78 RangeSet<Integer> rangeSet = TreeRangeSet.create(); 79 // [1,10] 80 rangeSet.add(Range.closed(1,10)); 81 // 不相連區間 [1,10] [11,15) 82 rangeSet.add(Range.closedOpen(11,15)); 83 // 相連合並[11,15)+[15,20)=[11,20),最終結果:[1,10] [11,20) 84 rangeSet.add(Range.closedOpen(15,20)); 85 // [1,10]-(5,10)=[1,5][10,10] ,最終結果:[1,5][10,10][11,20] 86 rangeSet.remove(Range.open(5,10)); 87 System.out.println("rangeSet="+rangeSet); 88 RangeMap<Integer,String> rangeMap = TreeRangeMap.create(); 89 rangeMap.put(Range.closed(1,10),"區間1"); 90 // 不處理任何key的區間交集,只是簡單映射 91 rangeMap.put(Range.closed(5,20),"區間2"); 92 System.out.println("rangeMap="+rangeMap); 93 } 94 }
打印日誌以下:
1 ====1.Multiset======= 2 a:3 3 b:2 4 c:1 5 ====2.Multimap======= 6 鍵-值集合映射: 7 a:[4, 1] 8 b:[2] 9 c:[3] 10 鍵-單個值映射: 11 a:4 12 a:1 13 b:2 14 c:3 15 ====3.BiMap======= 16 鍵值對{a=1, b=2} 17 鍵值反轉:{1=a, 2=b} 18 ====4.Table======= 19 {a={b=1, c=2}, d={b=3}} 20 row a={b=1, c=2} 21 column b={a=1, d=3} 22 ====5.ClassToInstanceMap======= 23 {class java.lang.Integer=1, class java.lang.Double=2.0, class java.lang.Long=3} 24 ====6.RangeSet、RangeMap======= 25 rangeSet=[[1..5], [10..10], [11..20)] 26 rangeMap=[[1..5)=區間1, [5..20]=區間2]
提供java.util.Collections中沒有的集合工具
集合接口、所屬關係、Guava對應的工具映射關係以下表:
1 package guava.collect; 2 3 import com.google.common.base.Function; 4 import com.google.common.collect.ImmutableMap; 5 import com.google.common.collect.ImmutableSet; 6 import com.google.common.collect.Iterables; 7 import com.google.common.collect.Lists; 8 import com.google.common.collect.MapDifference; 9 import com.google.common.collect.Maps; 10 import com.google.common.collect.Sets; 11 import com.google.common.primitives.Ints; 12 13 import java.util.List; 14 import java.util.Map; 15 import java.util.Set; 16 17 /** 18 * @Description 19 * @author denny 20 * @date 2018/7/27 下午2:46 21 */ 22 public class UtilityClassesTest { 23 24 public static void main(String[] args) { 25 /** 1.Iterables 迭代器工具集 */ 26 System.out.println("=========Iterables========="); 27 Iterable<Integer> concate = Iterables.concat(Ints.asList(1,2,3),Ints.asList(2,3,4)); 28 System.out.println("連接:"+concate); 29 System.out.println("元素2出現次數:"+Iterables.frequency(concate,2)); 30 System.out.println("按照指定長度拆分集合:"+Iterables.partition(concate,2)); 31 System.out.println("取第一個元素,爲空返回默認:"+Iterables.getFirst(concate,99)); 32 System.out.println("取最後元素:"+Iterables.getLast(concate)); 33 34 /** 2.Lists 列表工具集 */ 35 System.out.println("=========Lists========="); 36 List list = Lists.newArrayList(1,2,3,4,5); 37 System.out.println("反轉:"+Lists.reverse(list)); 38 System.out.println("拆分:"+Lists.partition(list,2)); 39 40 /** 3.Sets 集合工具集 */ 41 System.out.println("=========Sets========="); 42 Set<Integer> set1 = Sets.newHashSet(1,2,3); 43 Set<Integer> set2 = Sets.newHashSet(3,4,5); 44 System.out.println("並集:"+Sets.union(set1,set2)); 45 System.out.println("交集:"+Sets.intersection(set1,set2)); 46 System.out.println("差集(set1有set2沒有):"+Sets.difference(set1,set2)); 47 System.out.println("並集-交集:"+Sets.symmetricDifference(set1,set2)); 48 System.out.println("笛卡爾積:"+Sets.cartesianProduct(set1,set2)); 49 System.out.println("所有子集:"); 50 Sets.powerSet(set1).forEach(System.out::println); 51 52 /** 4.Maps 集合工具集 */ 53 System.out.println("=========Maps========="); 54 Map<String,Integer> map1 = Maps.newHashMap(); 55 map1.put("a",1); 56 map1.put("b",2); 57 map1.put("d",5); 58 Map<String,Integer> map2 = Maps.newHashMap(); 59 map2.put("a",1); 60 map2.put("b",3); 61 map2.put("c",4); 62 MapDifference<String,Integer> mapDifference = Maps.difference(map1,map2); 63 System.out.println("共有的:"+mapDifference.entriesInCommon()); 64 System.out.println("key相同,value不一樣:"+mapDifference.entriesDiffering()); 65 System.out.println("左邊獨有的:"+mapDifference.entriesOnlyOnLeft()); 66 System.out.println("右邊獨有的:"+mapDifference.entriesOnlyOnRight()); 67 // 字符串長度 68 ImmutableSet<String> allColors = ImmutableSet.of("red", "green", "blue"); 69 ImmutableMap<Integer,String> immutableMap = Maps.uniqueIndex(allColors, input -> input.length()); 70 System.out.println("字符串長度做爲惟一key:"+immutableMap); 71 } 72 }
打印結果以下:
=========Iterables========= 連接:[1, 2, 3, 2, 3, 4] 元素2出現次數:2 按照指定長度拆分集合:[[1, 2], [3, 2], [3, 4]] 取第一個元素,爲空返回默認:1 取最後元素:4 =========Lists========= 反轉:[5, 4, 3, 2, 1] 拆分:[[1, 2], [3, 4], [5]] =========Sets========= 並集:[1, 2, 3, 4, 5] 交集:[3] 差集(set1有set2沒有):[1, 2] 並集-交集:[1, 2, 4, 5] 笛卡爾積:[[1, 3], [1, 4], [1, 5], [2, 3], [2, 4], [2, 5], [3, 3], [3, 4], [3, 5]] 所有子集: [] [1] [2] [1, 2] [3] [1, 3] [2, 3] [1, 2, 3] =========Maps========= 共有的:{a=1} key相同,value不一樣:{b=(2, 3)} 左邊獨有的:{d=5} 右邊獨有的:{c=4} 字符串長度做爲惟一key{3=red, 5=green, 4=blue}
讓實現和擴展集合類變得更容易,好比建立Collection的裝飾器,或實現迭代器
不提供。guava本生就是JDK拓展,本身再去拓展,你再逗我嗎...
本文根據官方文檔簡單理解並使用了Guava Collect包下的類,主要包含Immutable Collections不可變集合、新集合類型、集合工具類、拓展工具類。其中前三個建議使用,最後一個拓展工具類就算了吧。
Guava其餘工具:https://www.cnblogs.com/dennyzhangdd/tag/google%20guava/