说个具体的应用场景吧:

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

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

Map<String,List<<Object>> myListMap test = new HashMap<String,List<Object>>()

然后你需要检查key是否存在,否则创建一个,最后代码成为这个样子:

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

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

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

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

Multimap<String,Object> myMultimap = ArrayListMultimap.create();

这里需要注意,所有的guava的集合都有create()方法,这个好处就是比较简单,你不用重复泛型信息了。

好了,开始使用Multimap了:


/** * Licensed to the Apache Software Foundation (ASF) under one or more* contributor license agreements.  See the NOTICE file distributed with* this work for additional information regarding copyright ownership.* The ASF licenses this file to You under the Apache License, Version 2.0* (the "License"); you may not use this file except in compliance with* the License.  You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.**/
package com.example.demo;import java.util.Arrays;
import java.util.Collection;import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;/**
* @desc: demo
* @name: MutliMapTest.java
* @author: tompai
* @email:liinux@qq.com
* @createTime: 2019年12月24日 下午12:53:43
* @history:
* @version: v1.0
*/public class MutliMapTest {public static void main(String... args) {Multimap<String, String> myMultimap = ArrayListMultimap.create();// Adding some key/valuemyMultimap.put("Fruits", "Bannana");myMultimap.put("Fruits", "Apple");myMultimap.put("Fruits", "Pear");myMultimap.put("Fruits", "Pear");myMultimap.put("Vegetables", "Carrot");// Getting the sizeint size = myMultimap.size();System.out.println(size); // 5// Getting valuesCollection<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 Mutlimapfor (String value : myMultimap.values()) {System.out.println(value);}// Removing a single valuemyMultimap.remove("Fruits", "Pear");System.out.println(myMultimap.get("Fruits")); // [Bannana, Apple, Pear]Collection<String> coll = myMultimap.replaceValues("Fruits", Arrays.asList("178","910",""));System.out.println("coll="+coll);System.out.println("myMultimap="+myMultimap);// Remove all values for a keymyMultimap.removeAll("Fruits");System.out.println(myMultimap.get("Fruits")); // [] (Empty Collection!)}
}

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

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

好了,基本就是这样。

Multimap的其它变种,和名字中的含义一样,各位适用于不同情况,只要在使用的时候择优选择即可:

1.ArrayListMultimap:
2.ForwardingMultimap:
3.HashMultimap:
4.ImmutableListMultimap:
5.ImmutableMultimap:
6.ImmutableSetMultimap:
7.LinkedHashMultimap:
8.LinkedListMultimap:
9.TreeMultimap;

Java一键多值Map 之Guava Multimap 用法简介相关推荐

  1. java 全局 map_java中map 9种常规用法

    通常来说,Map是一个由键值对组成的数据结构,且在集合中每个键是唯一的.下面就以K和V来代表键和值,来说明一下Java中关于Map的九大问题. 0.将Map转换为List类型 在java中Map接口提 ...

  2. java获取map遍历,Map获取键值,Map的几种遍历方法总结(推荐)

    Map以按键/数值对的形式存储数据,和数组非常相似,在数组中存在的索引,它们本身也是对象. Map的接口 Map---实现Map Map.Entry--Map的内部类,描述Map中的按键/数值对. S ...

  3. java 怎么获取键的值_在 Java 中如何获取 Map 的所有键和值

    在 Java 中可以通过 map.entrySet() 方法获取 Map 的所有键和值. Map map = new HashMap<>(); // Get keys and values ...

  4. C++ map容器和multimap容器(STL map容器)

    目录 1. 关联容器和map容器概述 2. map容器 2.1 map的创建以及初始化列表 2.2 map容器的一般常用属性(方法) 2.3 插入数据 2.4 数据的访问和遍历 2.5 数据的删除 2 ...

  5. java集合框架07——Map架构与源代码分析

    前几节我们对Collection以及Collection中的List部分进行了分析,Collection中还有个Set,因为Set是基于Map实现的,所以这里我们先分析Map,后面章节再继续学习Set ...

  6. 【Groovy】map 集合 ( 根据 Key 获取 map 集合中对应的值 | map.Key 方式 | map.‘Key’ 方式 | map[‘Key’] 方式 | 代码示例 )

    文章目录 一.根据 Key 获取 map 集合中对应的值 1.通过 map.Key 方式获取 map 集合中的值 Value 2.通过 map.'Key' 方式获取 map 集合中的值 Value 3 ...

  7. 转换实体类_利用Java反射机制进行Map和JavaBean间转换

    Java中利用反射进行Map和JavaBean间转换 在日常工作中,有时候我们可能会遇到以下这样的情况发生. 例如: (1)后端接受一个参数Map param(可能是前端form维护的一个对象...) ...

  8. Java 8 –按值对HashMap进行升序和降序排序

    在上一篇文章中,我向您展示了如何通过键对Java 8中的Map进行排序 ,今天,我将教您如何使用Java 8功能(例如,lambda表达式,方法引用,流和新方法) 按值对Map进行排序.添加到java ...

  9. java容器类2:Map及HashMap深入解读

    Java的编程过程中经常会和Map打交道,现在我们来一起了解一下Map的底层实现,其中的思想结构对我们平时接口设计和编程也有一定借鉴作用.(以下接口分析都是以jdk1.8源码为参考依据) 1. Map ...

  10. Java实现xml与map互转

    此文档中包含单层和多层嵌套情况下,xml和map集合进行互转,具体代码如下: import java.util.HashMap; import java.util.List; import java. ...

最新文章

  1. [转]让你提升命令行效率的 Bash 快捷键
  2. 《程序是怎么跑起来的》第六章
  3. 无尽包围html5游戏在线玩,小团体激发潜能小游戏突破自我
  4. java 正则表达式 逻辑符号
  5. Java基础学习总结(27)——7 款开源 Java 反编译工具
  6. oracle 历史查询是哪个机器发起的,Oracle 查询历史连接主机信息
  7. linux16.04设置网络,ubuntu16.04之后网络IP配置
  8. Ubuntu14.04 搜索不到WIFI或连接不上的解决方法。
  9. linux 邮件服务器pop3,linux下用pop3收web电子邮箱_邮件服务器
  10. 深度强化学习- 最全深度强化学习资料
  11. Performance Engineering of Software Systems (四) ——工具使用
  12. 算法与数据结构实验题 4.1 伊姐姐数字 game
  13. word利用宏批量调整图片大小
  14. java 转换成大写_java实现将数字转换成人民币大写
  15. 东方证券万字报告:微信视频号进入稳定的发展期
  16. 如何启用计算机安全模式,怎么进入电脑安全模式
  17. 酷狗音乐、QQ音乐、网易云音乐API
  18. 小白必看——炒币术语大盘点
  19. Android App开发动画特效之实现百叶窗动画和马赛克动画效果实战演示(附源码和演示视频 可直接使用)
  20. android属于数据库管理系统,详细谈谈Android系统中的SQLite数据库的应用

热门文章

  1. 《数学之美》—信息指纹及其应用
  2. 移动端安全 - 安卓Android - 工具相关
  3. PV EV AC BAC EAC ETC等计算公式
  4. golang的配置文件操作:viper
  5. 【ARM-Linux开发】ctrl-xxx的对应的signal含义
  6. Python学习之路day3-文件操作
  7. poj2488-A Knight's Journey【DFS】
  8. 【面试题37】两个链表的第一个公共结点
  9. 转:Qt 嵌入式开发环境搭建
  10. 洛谷1309 瑞士轮 解题报告