相信大家对Java中的Map类及其之类有大致的了解,Map类是以键值对的形式来存储元素(Key->Value),但是熟悉Map的人都知 道,Map中存储的Key是唯一的。什么意思呢?就是假如我们有两个key相同,但value不同的元素需要插入到map中去,那么先前的key对应的 value将会被后来的值替换掉。如果我们需要用Map来把相同key的值存在一起,代码看起来像下面一样:

    @Test
public void test1(){
List<Person> personList = new ArrayList<Person>();
Person person = new Person("孙刚1", "21", "男");
Person person2 = new Person("孙刚2", "21", "男");
Person person3 = new Person("孙刚3", "21", "女");
Person person4 = new Person("孙刚4", "21", "男");
Person person5 = new Person("孙刚5", "21", "女");
Person person6 = new Person("孙刚6", "21", "男"); personList.add(person);
personList.add(person2);
personList.add(person3);
personList.add(person4);
personList.add(person5);
personList.add(person6); genderStatistics(personList);
} //性别统计
public void genderStatistics(List<Person> personList){
Optional<List<Person>> optionalForPerson= Optional.fromNullable(personList);
if (!optionalForPerson.isPresent()) {
return;
} Map<String, List<Person>> map = new HashMap<String, List<Person>>();
for (Person person : personList) {
String sex = person.getSex();
List<Person> persons = map.get(sex);
if (null == persons) {//第一次加入
persons = new ArrayList<Person>();
} persons.add(person);
map.put(sex, persons);
} for(Entry<String, List<Person>> entry : map.entrySet()){
String key = entry.getKey();
System.out.println(key + ":" + entry.getValue());
}
}

结果如下:

    女:[Person [name=孙刚3, age=21, sex=女], Person [name=孙刚5, age=21, sex=女]]
男:[Person [name=孙刚1, age=21, sex=男], Person [name=孙刚2, age=21, sex=男], Person [name=孙刚4, age=21, sex=男], Person [name=孙刚6, age=21, sex=男]]

虽然实现了功能,但是代码比较长,但是如果你用Guava去实现同样的功能,你会发现你的代码一下子变少了。Guava提供了下面的结构

mport com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap; Multimap<K, V> myMultimap = ArrayListMultimap.create();

从名字可以看出,Multimap可以存放的key值是不唯一的,Multimap并没有实现 Map 的接口,所以不需要达到键唯一的要求。如果存放了key一样的元素,Multimap并不会覆盖以前相同的key元素,而是加进去了。结果有点像{k1= [v1, v2, v3], k2=[v7, v8],….}其中v1, v2, v3对应的key都是k1,而如果是Map,则它的结果有点像{k1=v1, k2=v2,…}看到区别了吧?那么,用Multimap实现上面同样的功能代码有点像

    Multimap<String, Person> myMultimap = ArrayListMultimap.create();
for (Person person : personList) {
String sex = person.getSex();
myMultimap.put(sex, person);
} Map<String, Collection<Person>> map1 = myMultimap.asMap();
for (Entry<String, Collection<Person>> entry : map1.entrySet()) {
String key = entry.getKey();
System.out.println(key + "\t" + entry.getValue());
}

看到了吧,代码简单多了吧!这里有一点你可能会疑惑,就是为何get方法返回的是一个Collection而不是list,这是因为前者会更加有用。如果 你需要基于multimap直接操作list或者set,那么可以在定义类型的时候使用子类名称:ListMultimap,SetMultimap和 SortedSetMultimap。例如:

    ListMutlimap<String,Person> myMutlimap = ArrayListMultimap.create();
// Returns a List, not a Collection.
List<Person> myValues = myMutlimap.get("myKey");

这里需要再次强调的是,Multimap不是Map(Multimap Is Not A Map)!

一 个Multimap<K, V>不是一个Map<K, Collection<V>>, 虽然我们可以利用Map<K, Collection<V>>来实现Multimap<K, V>,即使如此,它们之间还是有区别的:

  1. Multimap.get(key) 总是返回一个unll值(可能是一个空的collection);
  2. 可 以利用asMap()方法来得到一个 Map<K, Collection<V>>类型的数据(或者利用ListMultimap中的静态方法Multimaps.asMap()得到一个 Map<K, List<V>类型的数据; SetMultimap和SortedSetMultimap也类似);
  3. Multimap.containsKey(key)只有在这个key和一个或者多个元素相关联的时候才会返回true,如果这个key在删除之前和一个或者多个元素相关联则函数将会返回false;
  4. Multimap.entries()返回Multimap所有实体的所有key值;
  5. Multimap.size()返回在Multimap中存放的所有实体的数量,而不是不同keys的数量。我们可以利用Multimap.keySet().size()得到Multimap中所有不同keys的数量。

Guava API学习之Multimap的更多相关文章

  1. Guava API学习之Preconditions优雅的检验参数 编辑

    在日常开发中,我们经常会对方法的输入参数做一些数据格式上的验证,以便保证方法能够按照正常流程执行下去.对于可预知的一些数据上的错误,我们一定要做 事前检测和判断,来避免程序流程出错,而不是完全通过错误 ...

  2. Guava API学习之Ordering犀利的比较器 编辑

    Ordering是Guava类库提供的一个犀利强大的比较器工具,Guava的Ordering和JDK Comparator相比功能更强.它非常容易扩展,可以轻松构造复杂的comparator,然后用在 ...

  3. Guava API学习之Optional 判断对象是否为null

    java.lang.NullPointerException,只要敢自称Java程序员,那对这个异常就再熟悉不过了.为了防止抛出这个异常,我们经常会写出这样的代码: Person person = p ...

  4. [置顶] Guava学习之Multimap

    相信大家对Java中的Map类及其之类有大致的了解,Map类是以键值对的形式来存储元素(Key->Value),但是熟悉Map的人都知道,Map中存储的Key是唯一的.什么意思呢?就是假如我们有 ...

  5. guava API整理

    1,大纲 让我们来熟悉瓜娃,并体验下它的一些API,分成如下几个部分: Introduction Guava Collection API Guava Basic Utilities IO API C ...

  6. Openstack api 学习文档 & restclient使用文档

    Openstack api 学习文档 & restclient使用文档 转载请注明http://www.cnblogs.com/juandx/p/4943409.html 这篇文档总结一下我初 ...

  7. ASP.NET MVC Web API 学习笔记---第一个Web API程序

    http://www.cnblogs.com/qingyuan/archive/2012/10/12/2720824.html GetListAll /api/Contact GetListBySex ...

  8. Openstack python api 学习文档 api创建虚拟机

    Openstack python api 学习文档 转载请注明http://www.cnblogs.com/juandx/p/4953191.html 因为需要学习使用api接口调用openstack ...

  9. Windows录音API学习笔记(转)

    源:Windows录音API学习笔记 Windows录音API学习笔记 结构体和函数信息  结构体 WAVEINCAPS 该结构描述了一个波形音频输入设备的能力. typedef struct { W ...

随机推荐

  1. Python自动化运维之4、格式化输出、文件对象

    Python格式化输出: Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[P ...

  2. recovery编译汉化

    当BoardConfig.mk中定义了recovery的字体且为中文字体时,自动编译为中文版,否则编译为英文版 例如: BOARD_USE_CUSTOM_RECOVERY_FONT := \" ...

  3. [SQL注入3]from_sqli_to_shell_II

    [SQL注入1]这关学习盲注 ,这篇还有些东西没理透,后面搞明白了再修改. http://www.pentesterlab.com/exercises/from_sqli_to_shell_II/ 准 ...

  4. empty()方法

    empty()可以用来检查一个变量是否被声明或者值为false,通常被用来检查一个表单变量是否被发送或者包含数据. 例如一个登录表单: <?php if(!empty($_POST['uname ...

  5. TextView 超链接点击跳转到下一个Activity

    1:activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/androi ...

  6. android 适配器simpleadapter和baseadapter区别

    android 适配器 simpleadapter 和 baseadapter 设计网络程序或者数据处理显示程序的时候,常常会使用 simpleadapter 和baseadapter 来实现. ad ...

  7. Matrix控制平移、旋转和缩放的方法

    1.setTranslate(float ds,float dy):控制Matrix进行平移.2.setSkew(float kx,float ky,float px,float py):控制Matr ...

  8. 如何禁止KEIL初始化RAM为零& 如何判断是软复位还是上电复位

    (1)如何禁止KEIL初始化RAM为零? 1. 在KEIL Noinit 打钩 2. <1> 另须对需要热启动保持的变量用 _at_ 关键字指定某个区域,否则还是没用 <2>或 ...

  9. 为ownCloud配置SSL连接

    为ownCloud配置SSL连接 在你开始使用ownCloud之前,强烈建议你在ownCloud中启用SSL支持.使用SSL可以提供重要的安全好处,比如加密ownCloud流量并提供适当的验证.在本教 ...

  10. ~/.bashrc的常用alias设置

    centos6.5系统中,alias定义在/etc/bashrc,分别写在/etc/profile.d/*.sh中,可以在此目录添加my.sh, alias attrib='chmod'alias c ...