Multimap 用法简介

原创 2015年11月19日 15:33:05

简化你的 java map 操作:Guava 之 Multimap 用法简介

前不久在这篇 使用 Google Guava 美化你的 Java 代码:1~4 中的 “一个集合统治一切 – Multimap” 部分提到过这货,不过当时那篇文章受限于篇幅,例子举的不够详尽,估计很多同学看了还是云里雾里,一头雾水。

说个具体的应用场景吧:

比如现在我有一份日志记录,每条记录的内容是一个 url 对应一个访客的 userid,我现在想得到 每个 url 对应的 pv、uv 数据,你会怎么做?

普通青年一般这么想的:用 url 做 key,userid 作为对应 list 的内容:

1
Map<String,List<MyClass>> myClassListMap = new HashMap<String,List<MyClass>>()
然后你需要检查key是否存在,否则创建一个,最后代码成为这个样子: 
1
2
3
4
5
6
7
8
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);
}

如果你希望检查List中的对象是否存在,删除一个对象,或者遍历整个数据结构,那么需要更多的代码。 

看到这里不禁感叹一句:这特么都什么玩意啊。。。

恩,懒人总有懒人的办法,习惯脚本语言的我,很难忍受 java 的这种臃肿的代码了,下面看看用之前提到的 Guava MultiMap 怎么优雅的解决这个问题。

1
Multimap<String,Object> myMultimap = ArrayListMultimap.create();
这里需要注意,所有的guava的集合都有create()方法,这个好处就是比较简单,你不用重复泛型信息了。 

好了,开始使用Multimap了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.test;
 
import java.util.Collection;
 
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.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("Fruits", "Pear");
        myMultimap.put("Vegetables", "Carrot");
 
        // Getting the size
        int size = myMultimap.size();
        System.out.println(size); // 5
 
        // Getting values
        Collection<String> fruits = myMultimap.get("Fruits");
        System.out.println(fruits); //  [Bannana, Apple, Pear, Pear]
        System.out.println(ImmutableSet.copyOf(fruits));// [Bannana, Apple, Pear]
        // Set<Foo> set = Sets.newHashSet(list);
        // Set<Foo> foo = new HashSet<Foo>(myList);
 
        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, Apple, Pear]
 
        // Remove all values for a key
        myMultimap.removeAll("Fruits");
        System.out.println(myMultimap.get("Fruits")); // [] (Empty Collection!)
    }
}
这里有一点你可能会疑惑,就是为何get方法返回的是一个collection而不是list,这是因为前者会更加有用。如果你需要基于multimap直接操作list或者set,那么可以使用在定义类型的时候使用子类名称:ListMultimap,SetMultimap和SortedSetMultimap。例如: 

1
2
3
ListMutlimap<String,String> myMutlimap = ArrayListMultimap.create();
 
List<string> myValues = myMutlimap.get("myKey");  // Returns a List, not a Collection.
好了,基本就是这样,你可以参考API获取更多信息:

http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/index.html

PS: 下面再补充另一个问题:如何判断两个集合是否存在交集?

(1)普通写法:双层 for 循环遍历两个集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
boolean found = false;
for(Object1 object1 : list1){
   for(Object2 object2: list2){
       if(object1.getAttributeSame() == object2.getAttributeSame()){
           found = true;
           break;
           //also do something
       }
    }
    if(!found){
        //do something
    }
    found = false;
}
(2)JDK 自带的集合方法:disjoint
1
!Collections.disjoint(list1, list2);
(3) 使用第三方库: Apache Commons CollectionUtils

http://commons.apache.org/proper/commons-collections/javadocs/api-release/index.html

1
2
3
4
5
6
7
if(CollectionUtils.containsAny(list1,list2) 
    //do whatever
else{
     //do other thing
}
(4)不太高效的,但是简洁可用的变通方法:retainAll
1
2
if (!new HashSet<T>(list1).retainAll(list2).isEmpty())
    // at least one element is shared

(5)顺便说下如何求集合的包含、所属关系:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Test {
 
    public static void main(String[] args) throws IOException {
        Set a = new HashSet() {
            {
                add(1);
                add(2);
            }
        };
 
        Set b = new HashSet() {
            {
                add(2);
                add(3);
                add(1);
            }
        };
 
        System.out.println(b.containsAll(a));
        System.out.println(CollectionUtils.containsAll(b, a));
 
    }
 
}

Ref:

http://stackoverflow.com/questions/11796371/check-if-one-list-contains-element-from-the-other

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

简化你的 java map 操作:Guava 之 Multimap 用法简介

前不久在这篇 使用 Google Guava 美化你的 Java 代码:1~4 中的 “一个集合统治一切 – Multimap” 部分提到过这货,不过当时那篇文章受限于篇幅,例子举的不够详尽,估计很多...

简化你的 java map 操作:Guava 之 Multimap 用法简介

前不久在这篇  使用 Google Guava 美化你的 Java 代码:1~4  中的 “ 一个集合统治一切 – Multimap” 部分 提到过这货,不过当时那篇文章受限于篇幅,例子举的不够详...

map的用法实例(map和multimap)

map s;包含两个参数;键k与对象t 这里只介绍了常用的map与multimap,包括他们的实例操作和一些基本操作函数。 #include #include #include #include #i...

c++ map/multimap,set/multiset的用法及比较

一,相关介绍 map/multimap,set/multiset都为c++中的标准容器,它们的底层都是用红黑树实现的,因此在进行查询,修改,删除等操作上具有很高的效率,可以达到O(logN)。 那...

STL学习(六)--map/multimap用法详解

两者的内部结构都是用的是平衡二叉树,区别在于multimap允许重复元素而map不允许。 map和multimap**根据元素的key**自动对元素进行排序,要修改元素的key必须先删除拥有该key...

STL之六:map/multimap用法详解

map/multimap     使用map/multimap之前要加入头文件#include,map和multimap将key/value当作元素,进行管理。它们可根据key的排序准则自动将元素排...

STL:map/multimap用法详解

map/multimap    使用map/multimap之前要加入头文件#include,map和multimap将key/value当作元素,进行管理。它们可根据key的排序准则自动将元素排序。...

multimap用法示例

multimap用法示例 // multimaptest.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include #include ...

STL:map/multimap用法详解

map/multimap     使用map/multimap之前要加入头文件#include,map和multimap将key/value当作元素,进行管理。它们可根据key的排序准则自动将元素排...

stl::map,stl::multimap,boost::tuple使用简介

 一.Map1.前言在程序中,经常会遇见关联的数据对出现,可以把这个数据对中的一个称作索引值,另外一个称作关联值或映射值,假如索引值是整数的时候,可以采用数组或者向量存储这些数据对,但是假如索引值是其...
  • kfqcome
  • kfqcome
  • 2011年06月18日 15:29
  • 1339
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Multimap 用法简介
举报原因:
原因补充:

(最多只允许输入30个字)