guava中对Map的扩展数据结构

news2024/11/16 19:35:19
Multimap - 多值Map

guava中的Multimap提供了将一个键映射到多个值的形式,使用起来无需定义复杂的内层集合,可以像使用普通的Map一样使用它,定义及放入数据如下:

Multimap<String, Integer> multimap = ArrayListMultimap.create();
multimap.put("day",1);
multimap.put("day",2);
multimap.put("day",8);
multimap.put("month",3);

打印这个Multimap的内容,可以直观的看到每个key对应的都是一个集合:

{month=[3], day=[1, 2, 8]}
1、获取值的集合

在上面的操作中,创建的普通Multimapget(key)方法将返回一个Collection类型的集合:

Collection<Integer> day = multimap.get("day");

如果在创建时指定为ArrayListMultimap类型,那么get方法将返回一个List

ArrayListMultimap<String, Integer> multimap = ArrayListMultimap.create();
List<Integer> day = multimap.get("day");

同理,你还可以创建HashMultimapTreeMultimap等类型的Multimap

Multimapget方法会返回一个非null的集合,但是这个集合的内容可能是空,看一下下面的例子:

List<Integer> day = multimap.get("day");
List<Integer> year = multimap.get("year");
System.out.println(day);
System.out.println(year);


//打印结果:
[1, 2, 8]
[]
2、操作get后的集合

BiMap的使用类似,使用get方法返回的集合也不是一个独立的对象,可以理解为集合视图的关联,对这个新集合的操作仍然会作用于原始的Multimap上,看一下下面的例子:

ArrayListMultimap<String, Integer> multimap = ArrayListMultimap.create();
multimap.put("day",1);
multimap.put("day",2);
multimap.put("day",8);
multimap.put("month",3);

List<Integer> day = multimap.get("day");
List<Integer> month = multimap.get("month");

day.remove(0);//这个0是下标
month.add(12);
System.out.println(multimap);



//查看修改后的结果:
{month=[3, 12], day=[2, 8]}
3、转换为Map

使用asMap方法,可以将Multimap转换为Map<K,Collection>的形式,同样这个Map也可以看做一个关联的视图,在这个Map上的操作会作用于原始的Multimap

Map<String, Collection<Integer>> map = multimap.asMap();
for (String key : map.keySet()) {
    System.out.println(key+" : "+map.get(key));
}
map.get("day").add(20);
System.out.println(multimap);



//执行结果:
month : [3]
day : [1, 2, 8]
{month=[3], day=[1, 2, 8, 20]}
4、数量问题

Multimap中的数量在使用中也有些容易混淆的地方,先看下面的例子:

System.out.println(multimap.size());
System.out.println(multimap.entries().size());
for (Map.Entry<String, Integer> entry : multimap.entries()) {
    System.out.println(entry.getKey()+","+entry.getValue());
}



//打印结果:
4
4
month,3
day,1
day,2
day,8

这是因为size()方法返回的是所有key到单个value的映射,因此结果为4,entries()方法同理,返回的是key和单个value的键值对集合。但是它的keySet中保存的是不同的key的个数,例如下面这行代码打印的结果就会是2。

System.out.println(multimap.keySet().size());

再看看将它转换为Map后,数量则会发生变化:

Set<Map.Entry<String, Collection<Integer>>> entries = multimap.asMap().entrySet();
System.out.println(entries.size());

代码运行结果是2,因为它得到的是keyCollection的映射关系。

RangeMap - 范围Map

guava中的RangeMap描述了一种从区间到特定值的映射关系,让我们能够以更为优雅的方法来书写代码。下面用RangeMap改造上面的代码并进行测试:

RangeMap<Integer, String> rangeMap = TreeRangeMap.create();
rangeMap.put(Range.closedOpen(0,60),"fail");
rangeMap.put(Range.closed(60,90),"satisfactory");
rangeMap.put(Range.openClosed(90,100),"excellent");

System.out.println(rangeMap.get(59));
System.out.println(rangeMap.get(60));
System.out.println(rangeMap.get(90));
System.out.println(rangeMap.get(91));



//在上面的代码中,先后创建了[0,60)的左闭右开区间、[60,90]的闭区间、(90,100]的左开右闭区间,并分别映射到某个值上。运行结果打印:

fail
satisfactory
satisfactory
excellent

当然我们也可以移除一段空间,下面的代码移除了[70,80]这一闭区间后,再次执行get时返回结果为null

rangeMap.remove(Range.closed(70,80));
System.out.println(rangeMap.get(75));

ClassToInstanceMap - 实例Map

ClassToInstanceMap是一个比较特殊的Map,它的键是Class,而值是这个Class对应的实例对象。先看一个简单使用的例子,使用putInstance方法存入对象:

ClassToInstanceMap<Object> instanceMap = MutableClassToInstanceMap.create();
User user=new User("Hydra",18);
Dept dept=new Dept("develop",200);

instanceMap.putInstance(User.class,user);
instanceMap.putInstance(Dept.class,dept);



//使用getInstance方法取出对象:

User user1 = instanceMap.getInstance(User.class);
System.out.println(user==user1);

运行结果打印了true,说明了取出的确实是我们之前创建并放入的那个对象。

大家可能会疑问,如果只是存对象的话,像下面这样用普通的Map<Class,Object>也可以实现:

Map<Class,Object> map=new HashMap<>();
User user=new User("Hydra",18);
Dept dept=new Dept("develop",200);
map.put(User.class,user);
map.put(Dept.class,dept);

那么,使用ClassToInstanceMap这种方式有什么好处呢?

首先,这里最明显的就是在取出对象时省去了复杂的强制类型转换,避免了手动进行类型转换的错误。其次,我们可以看一下ClassToInstanceMap接口的定义,它是带有泛型的:

public interface ClassToInstanceMap<B> extends Map<Class<? extends B>, B>{...}

这个泛型同样可以起到对类型进行约束的作用,value要符合key所对应的类型,再看看下面的例子:

ClassToInstanceMap<Map> instanceMap = MutableClassToInstanceMap.create();
HashMap<String, Object> hashMap = new HashMap<>();
TreeMap<String, Object> treeMap = new TreeMap<>();
ArrayList<Object> list = new ArrayList<>();

instanceMap.putInstance(HashMap.class,hashMap);
instanceMap.putInstance(TreeMap.class,treeMap);

这样是可以正常执行的,因为HashMapTreeMap都集成了Map父类,但是如果想放入其他类型,就会编译报错:

所以,如果你想缓存对象,又不想做复杂的类型校验,那么使用方便的ClassToInstanceMap就可以了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2104488.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小琳Python课堂:Python高并发实现的基本原理(高阶版)

大家好&#xff0c;这里是小琳Python课堂&#xff01; 今天&#xff0c;我们将从高阶视角深入探讨Python高并发实现的基本原理&#xff0c;特别是线程安全性、线程同步和原子性这三个核心概念。这些概念对于构建复杂、高效的多线程应用程序至关重要。 线程安全性 首先&#x…

飞机制造5G智能工厂数字孪生工业物联平台,推进制造业数字化转型

飞机制造行业作为高端制造业的典范&#xff0c;正积极探索数字化转型的新路径。飞机制造5G智能工厂数字孪生工业物联平台&#xff08;以下简称“平台”&#xff09;的兴起&#xff0c;不仅为飞机制造业注入了强劲动力&#xff0c;更为整个制造业的数字化转型树立了新的标杆。 …

Java学习第七天

成员方法分类&#xff1a; 静态成员方法&#xff08;有static修饰 属于类&#xff09;建议用类名访问&#xff0c;也可以用对象访问 实例成员方法&#xff08;无static修饰 属于对象&#xff09;只能用对象出发访问 使用static来定义一些工具类 工具类直接使用类名.方法调用即…

Java并发线程 共享模型之管程 5

1. 生产者消费者 package cn.itcast.testcopy;import cn.itcast.n2copy.util.Sleeper; import lombok.extern.slf4j.Slf4j;import java.util.LinkedList;/*** ClassName: Test21* Package: cn.itcast.testcopy* Description: 生产者消费者** Author: 1043* Create: 2024/9/4 - …

Hadoop vs Spark

Hadoop 和 Spark 都是apache基金会下、在大数据架构中广泛使用的开源框架&#xff0c;两个框架都各自有各自的开源技术生态系统&#xff0c;用于准备、处理、管理和分析大数据集。 Hadoop 生态系统由四个主要模块组成: HDFS): Hadoop的数据存储系统&#xff0c;用于管理运行在普…

vue3中如何拿到element plus中el-tree多选的值?

在vue3中使用了element plus的el-tree组件 并将其设置为可选择的情况下如何拿到所选择的值&#xff1f; 首先我们要为el-tree设置show-checkbox&#xff08;它的作用是&#xff1a;节点是否可被选择&#xff09;&#xff0c;然后为el-tree绑定ref vue3中的ref跟vue2中的ref获取…

未来十年美业发展方向:健康与美容的结合|美业SaaS系统收银系统源码

随着人们对健康和美容的重视不断增加&#xff0c;美业正在经历一场革命性的变革。未来&#xff0c;美业的发展将更加注重健康与美容的结合&#xff0c;这一趋势将在多个领域产生深远影响。 下面博弈美业为大家阐释「为什么未来美业的发展方向是健康和美容的结合」&#xff1a;…

Java web开发常见中间件多版本下载备用

备注&#xff1a;每次换电脑都要重新构建一下环境&#xff0c;下载找资源很麻烦&#xff0c;官网英文网页找个历史版本看不懂&#xff0c;还要慢慢去搜&#xff0c;所以直接整理一波&#xff0c;需要的自行收藏。 1.nodejs自选版本下载&#xff1a; 地址&#xff1a;https://…

Facebook广告投放如何在节日季脱颖而出

众所周知&#xff0c;节日季是销售的旺季&#xff0c;根据统计基本都集中在年末。所以如果你想在今年的节日季大赚一笔&#xff0c;你需要从现在开始做准备工作&#xff0c;以便敲定你的节日季的营销策略。如果你感兴趣的话就继续看下去吧~ 1、设置转化API 在 Facebook 广告中…

leetcode回文链表

leetcode 回文链表 题目 题解 两种方式进行题解 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, Li…

[rk3399 android11]关闭声卡

使用以下命令查看声卡&#xff0c;可以看到目前有三个声卡 cat /proc/asound/cards 修改设备树 diff --git a/kernel/arch/arm64/boot/dts/rockchip/rk3399-jw-d039.dts b/kernel/arch/arm64/boot/dts/rockchip/rk3399-jw-d039.dtsindex 515334c127..5b592a852f 100755--- a/…

Unity Xcode方式接入sdk

入口 创建 GameAppController 类 继承 UnityAppController 并且在类的实现之前 需要 加 IMPL_APP_CONTROLLER_SUBCLASS(GameAppController)&#xff0c;表明这个是程序的入口。UnityAppController 实现了 UIApplicationDelegate。 可以简单看下 UIApplicationDelegate 的生命周…

[数据集][目标检测]智慧牧场猪只检测数据集VOC+YOLO格式16245张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;16245 标注数量(xml文件个数)&#xff1a;16245 标注数量(txt文件个数)&#xff1a;16245 标…

如何在算家云搭建ComfyUI(AI绘画)

一、ComfyUI简介 ComfyUI 是一个强大的、模块化的 Stable Diffusion 界面与后端项目。该用户界面将允许用户使用基于图形/节点/流程图的界面设计和执行高级稳定的扩散管道。该项目部分其它特点如下&#xff1a; 全面支持 SD1.x&#xff0c;SD2.x&#xff0c;SDXL&#xff0c;…

Java 入门指南:Java 并发编程 —— 并发容器 ArrayBlockingQueue

BlockingQueue BlockingQueue 是Java并发包&#xff08;java.util.concurrent&#xff09;中提供的一个阻塞队列接口&#xff0c;它继承自 Queue 接口。 BlockingQueue 中的元素采用 FIFO 的原则&#xff0c;支持多线程环境并发访问&#xff0c;提供了阻塞读取和写入的操作&a…

思维导图在线制作怎么制作?5个软件教你快速进行思维导图制作

思维导图在线制作怎么制作&#xff1f;5个软件教你快速进行思维导图制作 思维导图是一种用于组织信息、梳理思路和激发创意的可视化工具。在线制作思维导图可以帮助你随时随地进行创作和分享&#xff0c;以下是五款在线思维导图工具&#xff0c;可以帮助你快速进行思维导图的制…

props与defineProps

在 Vue3 中&#xff0c;script 脚本存在两种情况。一种是 setup 函数&#xff0c;一种是 <script setup>。而针对这两种不同情况&#xff0c;Vue 也存在 props 和 defineProps 两种接收父组件传递数据的形式。 首先&#xff0c;默认已掌握 Vue2 的父子组件 props 传参&a…

五轴数控走心机指的是哪五轴

五轴数控走心机&#xff0c;作为现代机械加工领域中的高精度设备&#xff0c;其核心在于其独特的五轴联动系统。这五个轴分别是X1轴、Y1轴、Z1轴、Z2轴和X2轴&#xff0c;它们各自承担着不同的运动和控制功能&#xff0c;共同实现了对工件的复杂加工。 X1轴&#xff1a;作为向下…

北芯生命持续亏损:产能利用率不理想仍扩产能,销售费用越来越高

《港湾商业观察》黄懿 6月29日&#xff0c;深圳北芯生命科技股份有限公司&#xff08;下称“北芯生命”&#xff09;提交首轮问询回复&#xff0c;更新2023年年报财务数据&#xff0c;保荐机构为中国国际金融股份有限公司。 据悉&#xff0c;北芯生命曾向港交所递交上市申请&…

[C++]AVL树插入和删除操作的实现

AVL树又称为高度平衡的二叉搜索树,是1962年由两位俄罗斯数学家G.M.Adel’son-Vel’skii和E.M.Landis提出的。ALV树提高了二叉搜索树树的搜索效率。为此,就必须每向二叉搜索树插人一个新结点时调整树的结构,使得二叉搜索树保持平衡,从而尽可能降低树的高度,减少树的平均搜索长度…