使用Google Guava来编写优雅的代码 – 集合3(Multimap)

前面针对Guava中的集合已经介绍了集合的创建和不可变集合以及Guava提供的新增加的集合类型Multiset,今天将继续为大家介绍Guava中的集合接口类Multimap及其一些相关的API用法。

由来

在我们日常的开发中,经常会需要使用到下面一种数据结构

Map<String,List<MyClass>> myClassListMap test2  
          = new HashMap<String,List<MyClass>>()

比如每个用户有多个手机号码或者联系地址,在这种情况下就有可能使用到以上的数据结构了。但是在使用这种数据结构时,我们需要关注的内容太多了,比如:

  • 在为某一个key的value添加元素时,我们需要先确认该value是否为空
  • 删除某一个key对应的value中某一个元素时,就需要进行遍历

通常情况我们编写的代码会像下面一段代码:

void putMyObject(String key, Object value) {  
    List<Object> myClassList = myClassListMap.get(key);  
    if(myClassList == null) {  
        myClassList = new ArrayList<object>();  
        myClassListMap.put(key,myClassList);  
    }  
    myClassList.add(value);  
}

这样编写代码的过程让我们不得不短暂的从关注的业务处理层面更多的转移到实现该数据结构的操作上,编写这样的代码也让代码显得有点难以阅读。

使用Guava Multimap

Guava对于Multimap提供了很多实现类,类似上面的功能需求,我们可以选择使用ArraylistMultimap。

首先让我们来看一段使用了Guava Multimap后的代码:

public class MutliMapTest {  
    public static void main(String... args) {  
      Multimap<String, String> myMultimap = ArrayListMultimap.create();  

      // Adding some key/value  
      myMultimap.put("Fruits", "Bannana");  
      myMultimap.put("Fruits", "Apple");  
      myMultimap.put("Fruits", "Pear");  
      myMultimap.put("Vegetables", "Carrot");  

      // Getting the size  
      int size = myMultimap.size();  
      System.out.println(size);  // 4  

      // Getting values  
      Collection<string> fruits = myMultimap.get("Fruits");  
      System.out.println(fruits); // [Bannana, Apple, Pear]  

      Collection<string> vegetables = myMultimap.get("Vegetables");  
      System.out.println(vegetables); // [Carrot]  

      // Iterating over entire Mutlimap  
      for(String value : myMultimap.values()) {  
       System.out.println(value);  
      }  

      // Removing a single value  
      myMultimap.remove("Fruits","Pear");  
      System.out.println(myMultimap.get("Fruits")); // [Bannana, Pear]  

      // Remove all values for a key  
      myMultimap.removeAll("Fruits");  
      System.out.println(myMultimap.get("Fruits")); // [] (Empty Collection!)  
    }  
} 

从上面的代码中我们可以发现Multimap提供了以下API:

  • put(K,V) :为指定的key添加一个value元素
  • putAll(K,Iterable) : 为指定的Key添加一组value元素。
  • remove(K,V) : 移除Key对应的某一个value元素。如果执行成功则返回true
  • removeAll(K) : 移除该Key所对应的所有value。
  • replaceValues(K,Iterable) : 替换Key所对应的Values。
  • values()

如果需要知道更多的API及其用法可以前往Guava的官方站点进行查看。

Multimap的实现类

实现类 Keys 的行为类似… Values的行为类似..
ArrayListMultimap HashMap ArrayList
HashMultimap HashMap HashSet
LinkedListMultimap* LinkedHashMap* LinkedList*
LinkedHashMultimap** LinkedHashMap LinkedHashSet
TreeMultimap TreeMap TreeSet
ImmutableListMultimap ImmutableMap ImmutableList
ImmutableSetMultimap ImmutableMap ImmutableSet

以上的实现类中除去不可修改的以外,其它的实现类均支持null的键和值。

更多资源