Guava - Collections - New collection types

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

 

Implementations

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 SetMultimapthis

和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没什么关系

Views

Multimap also supports a number of powerful views.

  • asMap views any Multimap<K, V> as a Map<K, Collection<V>>. The returned map supports remove, and changes to the returned collections write through, but the map does not support put or putAll. Critically, you can use asMap().get(key) when you want null on absent keys rather than a fresh, writable empty collection. (You can and should cast asMap.get(key) to the appropriate collection type -- aSet for a SetMultimap, a List for a ListMultimap -- but the type system does not allow ListMultimap to return Map<K, List<V>> here.)
  • entries views the Collection<Map.Entry<K, V>> of all entries in the Multimap. (For a SetMultimap, this is a Set.)
  • keySet views the distinct keys in the Multimap as a Set.
  • keys views the keys of the Multimap as a Multiset, with multiplicity equal to the number of values associated to that key. Elements can be removed from the Multiset, but not added; changes will write through.
  • values() views the all the values in the Multimap as a "flattened" Collection<V>, all as one collection. This is similar toIterables.concat(multimap.asMap().values()), but returns a full Collection instead.

  

Implementations

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.

 

总结:可以帮助自动分类,和以前的编程习惯有些不一样,须要些时间来适应,推荐

实用性:高

 

3.BiMap

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"));
}

Implementations 

Key-Value Map Impl Value-Key Map Impl Corresponding BiMap
HashMap HashMap HashBiMap
ImmutableMap ImmutableMap ImmutableBiMap
EnumMap EnumMap EnumBiMap
EnumMap HashMap EnumHashBiMap

 

总结:使用简单

实用性:中

 

4.Table

table是一种新的集合,提供了一种二重定位,能够认为是 行 加 列 定位一个值

 Table接口提供了如下几种实现方式。使用上很简单

  • HashBasedTable, which is essentially backed by a HashMap<R, HashMap<C, V>>.
  • TreeBasedTable, which is essentially backed by a TreeMap<R, TreeMap<C, V>>.
  • ImmutableTable, which is essentially backed by an ImmutableMap<R, ImmutableMap<C, V>>. (Note: ImmutableTable has optimized implementations for sparser and denser data sets.)
  • ArrayTable, which requires that the complete universe of rows and columns be specified at construction time, but is backed by a two-dimensional array to improve speed and memory efficiency when the table is dense. ArrayTable works somewhat differently from other implementations; consult the Javadoc for details.

 

    @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等对象定位。

总结:简单易懂,

实用性:中

5.ClassToInstanceMap

普通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那一章一块儿介绍

 

写的很差,欢迎指正,有时间会进一步完善

相关文章
相关标签/搜索