Guava提供了不少新的集合类型(这部分也是目前使用最广的)html
1.Multisetjava
The traditional Java idiom for e.g. counting how many times a word occurs in a document is something like:git
Map<String,Integer> counts =newHashMap<String,Integer>(); for(String word : words){ Integer count = counts.get(word); if(count ==null){ counts.put(word,1); }else{ counts.put(word, count +1); } }
在JDK中,List和Set有一个基本的区别,就是List能够包含多个相同对象,且是有顺序的,而Set不能有重复,且不保证顺序(有些实现有顺序,例如LinkedHashSet和SortedSet等)
因此Multiset占据了List和Set之间的一个灰色地带:容许重复,可是不保证顺序。
注意:这种集合在apache commons collections中也被称做“Bag”. apache
Guava provides many implementations of Multiset, which roughly correspond to JDK map implementations.编程
Map | Corresponding Multiset | Supports null elements |
HashMap | HashMultiset | Yes |
TreeMap | TreeMultiset | Yes (if the comparator does) |
LinkedHashMap | LinkedHashMultiset | Yes |
ConcurrentHashMap | ConcurrentHashMultiset | No |
ImmutableMap | ImmutableMultiset | No |
因而咱们使用Multiset就能很好的简化上面的代码app
package com.jake.guava.collections; import com.google.common.collect.HashMultiset; import com.google.common.collect.Multiset; import org.junit.Test; import java.util.List; import java.util.Map; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; /** * User: jake * Date: 13-10-11 * Time: 上午11:27 */ public class MultiSetTest { @Test public void countWorldByMultiSetTest() { List<String> words = newArrayList("a", "b", "b", "b", "b", "b", "fdsf", "fdsf", "fdsf"); Map<String, Integer> counts = newHashMap(); Multiset wordSet = HashMultiset.create(); for (String word : words) { wordSet.add(word); } System.out.println(wordSet.size()); System.out.println(wordSet.elementSet().size()); } @Test public void countWorldCommonTest() { List<String> words = newArrayList("a", "b", "b", "b", "b", "b", "fdsf", "fdsf", "fdsf"); Map<String, Integer> counts = newHashMap(); for (String word : words) { Integer count = counts.get(word); if (count == null) { counts.put(word, 1); } else { counts.put(word, count + 1); } } } }
总结:JDK中没出现的集合类型,实际中用到的地方仍是不少的ide
实用性:高 ui
2.Multimap(ListMultimap or SetMultimap)this
和MultiSet一样有个Multi ,官网上也说明 Guava's Multimapframework makes it easy to handle a mapping from keys to multiple valuesgoogle
说明了,Multimap是用来处理一个key对应多个值,也就是 Map<K, List<V>> or Map<K, Set<V>> 这两种状况。(不包含 Map<K,Map<K,V>这种状况)
通常咱们处理Map<K, List<V>> or Map<K, Set<V>> 这种稍显复杂的结构,以下:
应用场景仍是比较多的,例如:
学校每一个班的学生总数,Map<class,List<Student>>
医院每一个病房的病人信息,Map<room,List<Patient>>
咱们拿医院来举例,例如如今303病房要添加一个病人,
代码会是如此
@Test public void multiMapCommonTest(){ List<Patient> pList = newArrayList(new Patient(1,"lucy",303),new Patient(2,"lily",303)); Map<Integer,List<Patient>> patientList = newHashMap(); patientList.put(303, pList); //此时要入住一个病人到303 Patient p = new Patient(3,"jake",303); List<Patient> patients = patientList.get(303); if (patients != null) { patients.add(p); } else { patients = newArrayList(); patients.add(p); } } @Test public void multiMapGuavaTest() { //这里要改变一个思路,之前用 Map<K,List<V>> 来存储 //如今用 Multimap<K,V> 来存储 Multimap<Integer, Patient> patients = ArrayListMultimap.create(); patients.put(303,new Patient(1,"lucy",303)); patients.put(303,new Patient(1,"lily",303)); //此时要入住一个病人到303 Patient p = new Patient(3,"jake",303); Patient pAnother = new Patient(4,"jone",304); patients.put(303, p); patients.put(304, pAnother); for (Patient patient :patients.get(303) ) { System.out.println(patient); } }
//Multimap 也能够经过asMap 转为 Map<K,Collection<V>>形式 Map<Integer,Collection<Patient>> patientmap = patients.asMap();
官方提供了不少View,如下这些那就都属于java基础数据的处理了,和Guava没什么关系
Multimap also supports a number of powerful views.
Multimap provides a wide variety of implementations. You can use it in most places you would have used a Map<K, Collection<V>>.
Implementation Keys behave like... Values behave like..
ArrayListMultimap HashMap ArrayList
HashMultimap HashMap HashSet
LinkedListMultimap* LinkedHashMap* LinkedList*
LinkedHashMultimap** LinkedHashMap LinkedHashSet
TreeMultimap TreeMap TreeSet
ImmutableListMultimap ImmutableMap ImmutableList
ImmutableSetMultimap ImmutableMap ImmutableSet
也就是说会有不少种形式,
Multimap<String, Object> multimap_1 = ArrayListMultimap.create(); Multimap<String, Object> multimap_2 = HashMultimap.create(); Multimap<String, Object> multimap_3 = LinkedListMultimap.create();
依然没有 Map<K,Map<K,V>>的形式!
Each of these implementations, except the immutable ones, support null keys and values.
总结:可以帮助自动分类,和以前的编程习惯有些不一样,须要些时间来适应,推荐
实用性:高
BiMap双向或者叫作反向映射,就是经过value找key,普通思路就是维护着两个同步的Map , keyMap 和valueMap,可是这样作容易出错!
Guava提供BiMap的inverse()方法来实现,
@Test public void biMapTest(){ ImmutableMap<Integer,String> map = ImmutableMap.of(1,"303",2,"304"); BiMap<Integer, String> biMap = HashBiMap.create(map); System.out.println(biMap.inverse().get("304")); }
Key-Value Map Impl | Value-Key Map Impl | Corresponding BiMap |
HashMap | HashMap | HashBiMap |
ImmutableMap | ImmutableMap | ImmutableBiMap |
EnumMap | EnumMap | EnumBiMap |
EnumMap | HashMap | EnumHashBiMap |
总结:使用简单
实用性:中
table是一种新的集合,提供了一种二重定位,能够认为是 行 加 列 定位一个值
Table接口提供了如下几种实现方式。使用上很简单
@Test public void tableTest() { Table<Integer,Integer,String> table = HashBasedTable.create(); table.put(1, 1, "first row first column"); table.put(1, 2, "first row second column"); table.put(2,1,"second row first column"); System.out.println(table.get(1,2)); Table<Book, Integer, String> test = HashBasedTable.create(); }
可使用Integer定位,也可使用Book等对象定位。
总结:简单易懂,
实用性:中
普通Map是K ,V 键值对,ClassToInstanceMap是 class ,V的键值对形式(加泛型后就没意义了,只能存放一种对象,或者这种对象的子类对象)
示例代码:
@Test public void classToInstanceMapTest(){ ClassToInstanceMap classToInstanceMapString =MutableClassToInstanceMap.create(); classToInstanceMapString.put(String.class, ""); classToInstanceMapString.put(Integer.class, 1); Book book = new Book(1,"ST10001","三国志"); classToInstanceMapString.put(Book.class, book); }
总结:简单易懂,
实用性:中偏低
剩下的RangeSet和RangeMap等Range那一章一块儿介绍
写的很差,欢迎指正,有时间会进一步完善