摘要
Google Guava Collections 是 Java 领域的明珠,它的 API 完美地拓展了 Java Collections Framework,让人们对它赞不绝口。它的使用方法简单易懂,功能强大,让 Java 编程变得更加轻松愉快。
正文
Google Guava Collections 应用详细介绍
介绍
Google Guava Collections 是一个对 Java Collections Framework 提高和拓展的一个开源软件。因为它高品质 API 的完成和对 Java特点的灵活运用,促使其在 Java 小区遭受很高点评。小编关键详细介绍它的基本上使用方法和作用特点。
应用详细介绍
-
Google Guava Collections(下列都通称为 Guava Collections)是 Java Collections Framework 的提高和拓展。每一个 Java 开发人员都是会在工作上应用各种各样算法设计,许多 状况下 Java Collections Framework 能够 协助你进行这类工作中。
-
可是在有一些场所你应用了 Java Collections Framework 的 API,但或是必须写许多 编码来完成一些繁杂逻辑性, 这个时候就可以试着应用 Guava Collections 来协助你进行这种工作中。这种高品质的 API 使你的编码更短,更便于阅 读和改动,工作中更为轻轻松松。
总体目标阅读者
- 针对了解 Java 开源系统专用工具而言,文中阅读者最少应具有基本的 Java 专业知识,尤其是 JDK5 的特点。
- 由于 Guava Collections 充足应用了范型,循环系统提高那样的特点。做为 Java Collections Framework 的提高,阅读者务必对 Java Collections Framework 有清楚的了解,包含关键的插口承诺和常见的完成类。
- 而且 Guava Collections 非常大水平上是协助开发人员进行较为复杂的算法设计的实际操作,因而基本的算法设计和优化算法的专业知识也是清楚了解 Guava Collections 的 必备条件。
项目可行性
-
Guava Collections 是 Google 的技术工程师 Kevin Bourrillion 和 Jared Levy 在知名”20%”時间写的编码。自然做为开源软件也有别的的开发人员奉献了编码。
-
在撰写的全过程中,Java Collections Framework 的创作者 Joshua Bloch 也参加了编码审批和提意见。
-
现阶段它早已移到此外一个叫 guava-libraries 的开源软件下边来维护保养。 由于作用类似并且又同为开源软件,大家非常当然会把它和 Apache Commons Collections 来做比较。
结合详细介绍
-
Immutable Collections: 仍在应用 Collections.unmodifiableXXX() ? Immutable Collections 这才算是真真正正的不 可改动的结合 l Multiset: 看一下怎样把反复的原素放进一个结合。
-
Multimaps: 必须在一个 key 相匹配好几个 value 的情况下 , 自身写一个完成较为繁杂,让 Multimaps 来帮助
-
BiMap: java.util.Map 只有确保 key 的不反复,BiMap 确保 value 都不反复 l
-
MapMaker: 非常强劲的 Map 结构类
-
Ordering class: 大伙儿了解用 Comparator 做为电压比较器来对结合排列,可是针对多关键词排列 Ordering class 能够 简单化许多 的编码
Immutable Collections: 真真正正的不能改动的结合
- 大家都使用过Collections.unmodifiableXXX() 来做一个不能改动的结合。比如你需要结构储存变量定义的Set。
Set<String> set = new HashSet<String>(Arrays.asList(new String[]{"RED", "GREEN"}));
Set<String> unmodifiableSet = Collections.unmodifiableSet(set);
-
每一次调 unmodifiableSet.add() 会抛出去个 UnsupportedOperationException。
-
假如有些人在原先的set上add或是remove元素会怎么样?結果unmodifiableSet也是被 add 或是 remove 原素了。
结构那样一个简易的set写了几句长的编码。下边看一下ImmutableSet 是怎么来做地更安全性和简约 :
ImmutableSet<String> immutableSet = ImmutableSet.of("RED", "GREEN");
- 并且尝试调 add 方式的情况下,它一样会抛出去 UnsupportedOperationException,关键的是编码的易读性提高了许多,十分形象化地呈现了编码的作用。假如像以前这一编码维护一个set 怎么做呢?**
ImmutableSet<String> immutableSet = ImmutableSet.copyOf(set);
从结构的方法而言,ImmutableSet 结合还给予了 Builder 方式来结构一个结合 :在这个事例里边 Builder 不仅能添加单独原素还能添加不仅有的结合。
Builder<String> builder = ImmutableSet.builder();
ImmutableSet<String> immutableSet = builder.add("RED").addAll(set).build();
Guava Collections 还给予了各种各样 Immutable 结合的完成
-
ImmutableList
-
ImmutableSet
ImmutableSet.of(4, 8, 15, 16, 23, 42);
ImmutableSet.copyOf(numbers);
- ImmutableSortedSet
- ImmutableMap
public static final ImmutableMap<String, Integer>
ENGLISH_TO_INT = ImmutableMap
.with("four", 4)
.with("eight", 8)
.with("fifteen", 15)
.with("sixteen", 16)
.with("twenty-three", 23)
.with("forty-two", 42)
.build();
ImmutableMap.of(1, "one", 2, "two");
- ImmutableSortedMap (one day)
Multiset: 把反复的原素放进结合
-
你很有可能要说这和 Set 插口的合同矛盾,由于Set插口的 JavaDoc 里边要求不可以放进反复原素。实际上,Multiset 并 沒有完成 java.util.Set 插口,它更好像一个Bag。一般的 Set 如同那样 :[car, ship, bike],而 Multiset 会是那样 :
[car x 2, ship x 6, bike x 3]。 -
例如一个 List 里边有各种各样字符串数组,随后你需要统计分析每一个字符串数组在 List 里边发生的频次:
Map<String, Integer> map = new HashMap<String, Integer>();
for(String word : wordList){
Integer count = map.get(word);
map.put(word, (count == null) ? 1 : count 1);
}
//count word “the” Integer count = map.get(“the”);
假如用 Multiset 就可以那样 :
HashMultiset<String> multiSet = HashMultiset.create();
multiSet.addAll(wordList);
//count word “the” Integer count = multiSet.count(“the”);
-
那样连循环系统都不需要了,并且 Multiset 用的方式叫 count,显而易见比在 Map 里边调 get 有更强的易读性。
-
Multiset 还给予了 setCount 那样设置原素反复频次的方式,尽管你能根据应用 Map 来完成相近的作用,可是程序流程的易读性比 Multiset 差了许多 。
常见完成 Multiset 插口的类有:
- HashMultiset: 原素储放于HashMap
- LinkedHashMultiset: 原素储放于 LinkedHashMap,即原素的顺序排列由第一次放进的次序决策
- TreeMultiset:原素被排列储放于TreeMap
- EnumMultiset: 原素务必是 enum 种类
- ImmutableMultiset: 不能改动的 Mutiset
- 见到这儿你很有可能早已发觉 Guava Collections 全是以 create 或者 of 那样的静态方法来结构目标。这是由于这种结合
- 类大多数有好几个主要参数的独享构造函数,因为主要参数数量许多 ,顾客编码程序猿应用起來就很不方便。并且以这类方法能够
- 回到原种类的子种类目标。此外,针对建立范型目标而言,这类方法更为简约。
见到这儿你很有可能早已发觉 Guava Collections 全是以 create 或者 of 那样的静态方法来结构目标。这是由于这种结合类大多数有好几个主要参数的独享构造函数,因为主要参数数量许多 ,顾客编码程序猿应用起來就很不方便。并且以这类方法能够
回到原种类的子种类目标。此外,针对建立范型目标而言,这类方法更为简约。
Multimap: 在 Map 的 value 里边放好几个原素
Multimap便是一个 key 相匹配好几个 value 的算法设计。看起来它很像 java.util.Map 的构造,可是 Muitimap 并不是 Map,沒有完成 Map 的插口。构想你对 Map 调了 2 次主要参数 key 一样的 put 方式,結果便是第 2 次的 value 遮盖
了第 1 次的 value。可是对 Muitimap 而言这一 key 与此同时相匹配了 2 个 value。因此 Map 看起来是 : {k1=v1, k2=v2,…},而 Muitimap 是 :{k1=[v1, v2, v3], k2=[v7, v8],….}。
- 举个记名投票的事例,全部选举票都放到一个 List
里边,List 的每一个原素包含网络投票人与大选人名字。
我们可以那样写 :
//Key is candidate name, its value is his voters
HashMap<String, HashSet<String>> hMap = new HashMap<String, HashSet<String>>();
for(Ticket ticket: tickets){
HashSet<String> set = hMap.get(ticket.getCandidate());
if(set == null){
set = new HashSet<String>();
hMap.put(ticket.getCandidate(), set);
}
set.add(ticket.getVoter());
}
大家再一起来看看 Muitimap 能做些哪些 :
HashMultimap<String, String> map = HashMultimap.create();
for(Ticket ticket: tickets){
map.put(ticket.getCandidate(), ticket.getVoter());
}
就那么简易! 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
BiMap: 双重 Map
**BiMap 完成java.util.Map 插口。它的特性是它的value和它 key一样也是不能反复的,也就是说它的 key 和value是等额的的,假如你往 BiMap 的 value 里边放了反复的原素,便会获得 IllegalArgumentException。 **
举个事例,你很有可能常常会遇到在 Map 里边依据 value 值来推算它的 key 值的逻辑性:
for(Map.Entry<User, Address> entry : map.entreSet()){
if(entry.getValue().equals(anAddess)){
return entry.getKey();
}
}
return null;
- 假如把 User 和 Address 都放到 BiMap,那麼一句编码就获得結果了: return biMap.inverse().get(anAddess);
- 这儿的 inverse 方式便是把 BiMap 的 key 结合 value 结合互换,因而 biMap == biMap.inverse().inverse()。
BiMap的常见完成有:
- HashBiMap: key 结合与 value 结合都是有 HashMap 完成
- EnumBiMap: key 与 value 都务必是 enum 种类
- ImmutableBiMap: 不能改动的 BiMap
MapMaker: 非常强劲的 Map 结构专用工具
MapMaker 是用于结构 ConcurrentMap 的java工具。
为何能够 把 MapMaker 称为非常强劲?看过下边的事例你就知道了。最先,它能够 用于结构 ConcurrentHashMap:
//ConcurrentHashMap with concurrency level 8
ConcurrentMap<String, Object> map1 = new MapMaker().concurrencyLevel(8).makeMap();
或是结构用各种各样不一样 reference 做为 key 和 value 的 Map:
//ConcurrentMap with soft reference key and weak reference value
ConcurrentMap<String, Object> map2 = new MapMaker().softKeys().weakValues().makeMap();
或是结构有全自动清除時间到期项的 Map:
//Automatically removed entries from map after 30 seconds since they are created
ConcurrentMap<String, Object> map3 = new MapMaker()
.expireAfterWrite(30, TimeUnit.SECONDS)
.makeMap();
或是结构有较大限定数量的 Map:
//Map size grows close to the 100, the map will evict
//entries that are less likely to be used again
ConcurrentMap<String, Object> map4 = new MapMaker()
.maximumSize(100)
.makeMap();
或是给予当 Map 里边不包含所 get 的项,而必须全自动添加到 Map 的作用。这一作用当 Map 做为缓存文件的情况下很有 用 :
//Create an Object to the map, when get() is missing in map
ConcurrentMap<String, Object> map5 = new MapMaker().makeComputingMap(
new Function<String, Object>() {
public Object apply(String key) {
return createObject(key);
}});
这种还并不是最强劲的特点,最厉害的是 MapMaker 能够 给予有着之上全部特点的 Map:
//Put all features together!
ConcurrentMap<String, Object> mapAll = new MapMaker()
.concurrencyLevel(8)
.softKeys()
.weakValues()
.expireAfterWrite(30, TimeUnit.SECONDS)
.maximumSize(100)
.makeComputingMap(
new Function<String, Object>() {
public Object apply(String key) {
return createObject(key);
}});
Ordering class: 灵便的多字段名排列电压比较器
要对结合排列或是求最高值极小值,首先推荐 java.util.Collections 类,但关键是要给予 Comparator 插口的完成。假定有 个待排列的 List
Collections.sort(list, new Comparator<Foo>(){
@Override
public int compare(Foo f1, Foo f2) {
int resultA = f1.a – f2.a;
int resultB = f1.b – f2.b;
return resultA == 0 ? (resultB == 0 ? f1.c – f2.c : resultB) : resultA;
}});
这看起来有点儿眼花,假如用一串 if-else 也罢不上哪儿去。看一下 ComparisonChain 能保证哪些 :
Collections.sort(list, new Comparator<Foo>(){
@Override
return ComparisonChain.start()
.compare(f1.a, f2.a)
.compare(f1.b, f2.b)
.compare(f1.c, f2.c).result();
}});
假如排列关键词要用自定电压比较器,compare 方式也是有接纳 Comparator 的轻载版本号。例如 Foo 里边每一个排列关键词都早已拥有分别的 Comparator,那麼运用 ComparisonChain 能够 :
Collections.sort(list, new Comparator<Foo>(){
@Override
return ComparisonChain.start()
.compare(f1.a, f2.a, comparatorA)
.compare(f1.b, f2.b, comparatorB)
.compare(f1.c, f2.c, comparatorC).result();
}});
Ordring 类还给予了一个组成 Comparator 目标的方式。并且 Ordring 自身完成了 Comparator 插口因此 它能立即作 为 Comparator 应用:
Ordering<Foo> ordering = Ordering.compound(Arrays.asList(comparatorA, comparatorB, comparatorc));
Collections.sort(list, ordering);
过滤装置(stream-filter)
运用 Collections2.filter() 方式过虑结合中不满足条件的原素。例如过虑一个 List
原素 :
Collection<Integer> filterCollection =
Collections2.filter(list, new Predicate<Integer>(){
@Override
public boolean apply(Integer input) {
return input >= 10;
}});
-
自然,你能自身写一个循环系统来完成这一作用,可是那样不可以确保以后低于 10 的原素不被放进结合。
-
filter 的强劲之 处取决于回到的 filterCollection 依然有抵触低于 10 的原素的特点,假如调 filterCollection.add(9) 便会获得一个IllegalArgumentException。
转化器(Stream-map)
运用 Collections2.transform() 方式来变换结合中的原素。例如把一个 Set
Collection<String> formatCollection =
Collections2.transform(set, new Function<Integer, String>(){
@Override
public String apply(Integer input) {
return new DecimalFormat("#,###").format(input);
}} );
汇总
之上详细介绍了 Guava Collections 的一些基本上的作用特点。你能从 guava-libraries 的官网免费下载它的 jar 包和它别的的有关文本文档。假如你应用 Maven 来管理方法你的新项目依赖包,Maven 中间库也给予了它版本号的依靠。最后希望Guava Collections 使你的程序编写工作中更轻轻松松,更有快乐。
应用
这一开源软件公布的 jar 包能够 在它的官网内(http://code.google.com/p/guava-libraries/downloads/list)寻找。
其免费下载的 zip 库中带有 Guava Collections 的 jar 包 guava-r09.jar 以及依赖包 guava-r09-gwt.jar,javadoc,源码,readme 等文档。应用时只需将 guava-r09.jar 和依赖包 guava-r09-gwt.jar 放进 CLASSPATH 中就可以。
假如您应用 Maven 做为搭建专用工具得话能够 在 pom.xml 内添加:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>xxx</version>
</dependency>
关注不迷路
扫码下方二维码,关注宇凡盒子公众号,免费获取最新技术内幕!
评论0