Guava 3: 集合Collections

一、引子

Guava 对JDK集合的拓展,是最成熟且最受欢迎的部分。本文属于Guava的核心,需要仔细看。

二、Guava 集合

2.1 Immutable Collections不可变集合

1.作用

用不变的集合进行防御性编程和性能提升。

2.简单使用

 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]

2.2 新集合类型

1.作用

提供multisets, multimaps, tables, bidirectional maps等,方便各种使用场景。

2.简单使用

很多类,我们只举例分析multiset、multimap接口,其它的就在测试类中体现。

multiset接口

继承自JDK:java.util.Collection接口,支持多次添加相同的元素,且无序。

当把Multiset看成普通的Collection时,它表现得就像无序的ArrayList:

  • add(E)添加单个给定元素
  • iterator()返回一个迭代器,包含Multiset的所有元素(包括重复的元素)
  • size()返回所有元素的总个数(包括重复的元素)

当把Multiset看作Map<E, Integer>时,它也提供了符合性能期望的查询操作:

  • count(Object)返回给定元素的计数。HashMultiset.count的复杂度为O(1),TreeMultiset.count的复杂度为O(log n)。
  • entrySet()返回Set<Multiset.Entry<E>>,和Map的entrySet类似。
  • elementSet()返回所有不重复元素的Set<E>,和Map的keySet()类似。
  • 所有Multiset实现的内存消耗随着不重复元素的个数线性增长。

multimap接口

  • 支持一个key映射多个value: k1-v1, k1-v2。
  • 提供asMap()视图,返回Map<K, Collection<V>>,即k1->v集合(v1,v2)

各种multimap实现类如下:

测试类如下:

 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]

2.3 强大的集合工具类

1.作用

提供java.util.Collections中没有的集合工具

2.简单使用

集合接口、所属关系、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}

2.4 扩展工具类

1.作用

让实现和扩展集合类变得更容易,比如创建Collection的装饰器,或实现迭代器

2.简单使用

不提供。guava本生就是JDK拓展,自己再去拓展,你再逗我吗...

三、总结

本文根据官方文档简单理解并使用了Guava Collect包下的类,主要包含Immutable Collections不可变集合、新集合类型、集合工具类、拓展工具类。其中前三个建议使用,最后一个拓展工具类就算了吧。

原文地址:https://www.cnblogs.com/dennyzhangdd/p/9378978.html

时间: 2024-10-17 02:18:14

Guava 3: 集合Collections的相关文章

[Guava学习笔记]Collections: 不可变集合, 新集合类型

不可变集合 不接受null值. 创建:ImmutableSet.copyOf(set); ImmutableMap.of(“a”, 1, “b”, 2); public static final ImmutableSet<Color> GOOGLE_COLORS = ImmutableSet.<Color>builder() .addAll(WEBSAFE_COLORS) .add(new Color(0, 191, 255)) .build(); 可以有序(如ImmutableS

guava学习--集合2

Table: 当我们需要多个索引的数据结构的时候,通常情况下,我们只能用这种丑陋的Map<FirstName, Map<LastName, Person>>来实现.为此Guava提供了一个新的集合类型-Table集合类型,来支持这种数据结构的使用场景.Table支持"row"和"column",而且提供多种视图. Table<String, Integer, String> aTable = HashBasedTable.crea

Java中的集合Collections(六)

操作集合的工具类Collections Java提供了一个操作Set.List和Map等集合的工具类:Collections,该工具类里提供了大量方法对集合元素进行排序.查询和修改等操作,还提供了将集合对象设置为不可变.对集合对象实现同步控制等方法. 排序操作 Collections提供了如下几个方法对List集合元素进行排序: static void reverse(List list);       //反转指定List集合元素的顺序. static void shuffle(List li

Guava新增集合类型-Multimap(3)

在日常的开发工作中,我们有的时候需要构造像Map<K, List<V>>或者Map<K, Set<V>>这样比较复杂的集合类型的数据结构,以便做相应的业务逻辑处理. Multimap Guava的Multimap就提供了一个方便地把一个键对应到多个值的数据结构.让我们可以简单优雅的实现上面复杂的数据结构,让我们的精力和时间放在实现业务逻辑上,而不是在数据结构上,下面我们具体来看看Multimap的相关知识点. 调用Multimap.get(key)会返回这个

Guava学习笔记:Guava新增集合类型-Bimap

BiMap提供了一种新的集合类型,它提供了key和value的双向关联的数据结构. 通常情况下,我们在使用Java的Map时,往往是通过key来查找value的,但是如果出现下面一种场景的情况,我们就需要额外编写一些代码了.首先来看下面一种表示标识序号和文件名的map结构.     @Test     public void logMapTest(){         Map<Integer,String> logfileMap = Maps.newHashMap();         log

Guava学习笔记:Guava新增集合类型-Multimap

在日常的开发工作中,我们有的时候需要构造像Map<K, List<V>>或者Map<K, Set<V>>这样比较复杂的集合类型的数据结构,以便做相应的业务逻辑处理.例如: import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.Test; public class MultimapTe

guava学习--集合1

Lists: 其内部使用了静态工厂方法代替构造器,提供了许多用于List子类构造和操作的静态方法,我们简单的依次进行说明,如下: newArrayList():构造一个可变的.空的ArrayList实例. newArrayList(E... elements):构造一个可变的包含传入元素elements的ArrayList实例. newArrayList(Iterable<? extends E> elements):构造一个可变的包含传入元素elements的ArrayList实例. new

线程高级应用-心得8-java5线程并发库中同步集合Collections工具类的应用及案例分析

1.  HashSet与HashMap的联系与区别? 区别:前者是单列后者是双列,就是hashmap有键有值,hashset只有键: 联系:HashSet的底层就是HashMap,可以参考HashSet的类源码,默认构造方法为: public HashSet(){ map = new HashMap<key,Object> } 就是HashSet只用HashMap的键,而不用他的值,前者的值可以程序员随便指定,反正不用 2.  线程并发库中的集合优路劣之分 HashMap和HashSet如果在

Java集合-Collections

Java Collections和Arrays的sort方法默认的排序方法是什么: 原文地址:https://www.cnblogs.com/zwhu1216/p/11376386.html