Guava学习之Multisets

2023-11-05

今天谈谈Guava类库中的Multisets数据结构,虽然它不怎么经常用,但是还是有必要对它进行探讨。我们知道Java类库中的Set不能存放相同的元素,且里面的元素是无顺序的;而List是能存放相同的元素,而且是有顺序的。而今天要谈的Multisets是能存放相同的元素,但是元素之间的顺序是无序的。从这里也可以看出,Multisets肯定不是实现Java中Set接口的,因为Set接口是不能存放相同的元素!Java中的Set 里面的元素有点像 :[A, C, B],而 Multiset 会是这样 : [A ×2, C ×3, B ×5],这个是有区别的。
在以前,如果我们需要统计一篇文章中各个单词出现的次数,我们可能用下面的方法来实现:

public void wordCounts(List words) {
	Map<String, Integer> counts = new HashMap<String, Integer>();
	for (String word : words) {
		Integer count = counts.get(word);
		if (count == null) {
			counts.put(word, 1);
		} else {
			counts.put(word, count + 1);
		}
	}
}

如果我们需要得到某个单词(比如good)的出现次数,我们可能这么写:

int goodCount = counts.get("good");

很麻烦对吗?而且Map中的get(E key)的含义都不那么明显。那如果我们用Multisets来看看:

import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;

Multiset countMultiset = HashMultiset.create();
countMultiset.addAll(words);

很简单吧?甚至连循环都不需要。那么我们怎么得到某个单词(比如good)的出现次数?很简单:

int goodCount= countMultiset .count(“good”);

在Multiset中提供了一个count(Object element)方法,得到某个对象在Multiset中出现的次数,这个显然比在Map里面调get的可读性好多了,不是吗?

需要注意Multiset提供setCount(E, int)方法,可以修改元素E在Multiset中的次数,但是不能把元素出现的次数修改为负数和大于Integer.MAX_VALUE的值。否则将会抛出异常

countMultiset .setCount("good", Integer.MAX_VALUE + 1);
或
countMultiset .setCount("good", -1);

将会抛出

Exception in thread "main" java.lang.IllegalArgumentException: count cannot be negative: -2147483648(-1)
	at com.google.common.base.Preconditions.checkArgument(Preconditions.java:119)
	at com.google.common.collect.Multisets.checkNonnegative(Multisets.java:1061)
	at com.google.common.collect.AbstractMapBasedMultiset.setCount(AbstractMapBasedMultiset.java:265)
	at com.google.common.collect.HashMultiset.setCount(HashMultiset.java:34)
	at com.wyp.test.testFiles(test.java:150)
	at com.wyp.test.main(test.java:156)

因为在Multiset中setCount先会判断所设置数据的状态

 static void checkNonnegative(int count, String name) {
	checkArgument(count >= 0, "%s cannot be negative: %s", name, count);
 }

可以看出,count是int类型的,最大的值为Integer.MAX_VALUE,在其基础只上加上1将会变成负数,所以不行。
  Multiset也不是Map<E, Integer>类型的结构, 我们可以用Map<E, Integer>来实现Multiset,但是利用Map<E, Integer>实现Multiset和Googleguava的实现还是有很大的区别的,主要表现如下:

  1. Multiset中的元素出现的次数只能为正数,前面说了原因。如果E的出现次数为0,那么E将不出现在multiset中,是不能在elementSet()和entrySet()的视图中;
  2. multiset.size()返回这个集合的大小,相当于在multiset中元素的出现的总数。如果想得到multiset中不同元素出现的总数,可以利用elementSet().size()来实现;
  3. multiset.iterator()可以遍历multiset中的所有元素,所以iteration遍历的次数就等于multiset.size();
  4. Multiset支持添加、删除元素,设置元素出现的次数;setCount(elem, 0)相当于移除elem的所有元素;
  5. multiset.count(elem)方法中的elem如果没有出现在Multiset中,那么它的返回值永远都是0。

  常用的实现了Multiset 接口的类有:

  1. HashMultiset: 元素存放于 HashMap
  2. LinkedHashMultiset: 元素存放于 LinkedHashMap,即元素的排列顺序由第一次放入的顺序决定
  3. TreeMultiset:元素被排序存放于TreeMap
  4. EnumMultiset: 元素必须是 enum 类型
  5. ImmutableMultiset: 不可修改的 Mutiset
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Guava学习之Multisets 的相关文章

随机推荐

  • 大学生数学建模优秀论文发表

    大学生数学建模优秀论文篇1 浅谈大学生数学建模的意义 摘 要 本文重点分析了数学建模对当前数学教育教学改革的现实意义 探讨了数学建模对学生应用数学能力的培养 阐述了计算机在数学建模竞赛中的作用和地位 最后介绍了数学建模对数学教学改革的启示意
  • 微信小程序-weUI组件库

    微信小程序的开发过程中 常常会出现很多重复性的功能翻来覆去地使用 那么直接用一套封装好的组件库 就能大大提升开发速度 微信小程序的UI组件库有很多 可以参考下面这个内容 微信小程序UI组件库合集 微信开放社区 qq com https de
  • 英伟达GPU驱动和CUDA的版本对应关系

    CUDA Toolkit Toolkit Driver Version Linux x86 64 Driver Version Windows x86 64 Driver Version CUDA 11 6 GA gt 510 39 01
  • 深入研究java.lang.ThreadLocal类

    深入研究java lang ThreadLocal类 一 概述 ThreadLocal是什么呢 其实ThreadLocal并非是一个线程的本地实现版本 它并不是一个Thread 而是threadlocalvariable 线程局部变量 也许
  • matlab的损失函数mse,MSELoss损失函数

    MSELoss损失函数中文名字就是 均方损失函数 公式如下所示 这里 loss x y 的维度是一样的 可以是向量或者矩阵 i 是下标 很多的 loss 函数都有 size average 和 reduce 两个布尔类型的参数 因为一般损失
  • 消费者与生产者模式(管程法、消息队列的方法)

    生产者和消费者模式 管程法SynContainer 我们知道wait notify notifyAll 方法都是java lang Object类的 native方法 如果我们要在某个线程中的synchronized块中调用 wait no
  • activiti7的网关

    工作流 activiti7网关 1 排他网关 排他网关 也叫异或 XOR 网关 或叫基于数据的排他网关 用来在流程中实现决策 当流程执行到这个网关 所有分支都会判断条件是否为true 如果为 true 则执行该分支 注意 排他网关只会选择一
  • Hbase基础入门

    HBase 1 HBase是什么 1 1 HBase的概念 1 2 HBase的特点 2 HBase集群安装部署 2 1 准备安装包 2 2 修改HBase配置文件 2 2 1 hbase env sh 2 2 2 hbase site x
  • RocketMQ入门

    1 认识MQ 1 1 什么是MQ MQ全称为Message Queue 即消息队列 是一种提供消息队列服务的中间件 也称为消息中间件 是一套提供了消息生 产 存储 消费全过程的软件系统 遵循FIFO原则 1 2 为什么用MQ 并发量高时 当
  • 微信小程序 组件生命周期

    完整微信小程序 Java后端 技术贴目录清单页面 必看 组件的生命周期 指的是组件自身的一些函数 这些函数在特殊的时间点或遇到一些特殊的框架事件时被自动触发 其中 最重要的生命周期是 created attached detached 包含
  • yolov5详解与改进

    https github com z1069614715 objectdetection script YOLOV5改进 Optimal Transport Assignment Optimal Transport Assignment O
  • 49天精通Java,第43天,缓冲区数据结构bytebuffer

    目录 专栏导读 一 缓冲区 二 常用方法 三 通道获取 1 从 FileInputStream FileOutputStream 中获取 2 从 RandomAccessFile 中获取 3 通过 FileChannel open 获取 四
  • 如何创建A/B Test谷歌广告实验(3种类型)

    为了更精细化的测试广告 我们需要做一些测试 谷歌广告实验 我们也经常会叫A B Test 目前谷歌支持搜索广告 展示广告和视频广告三种广告系列类型的A B Test 在谷歌广告实验中分为广告变体 自定义实验和视频实验三种类型 广告变体主要用
  • Hadoop集群完全分布式搭建

    本人也只是hadoop学习的一个萌新 在这段时间内因为课程的需要 安装了一下hadoop集群 里面遇到了一些问题 找到了一些解决办法 如果文章内有什么错误 欢迎大家与我交流 下面就开始搭建hadoop集群吧 搭建环境为win10 虚拟机为V
  • 在Linux环境搭建Java版Minecraft(我的世界)服务器

    文章目录 前言 一 帮助轻松开服的工具 1 Xshell 2 XFTP 二 开服步骤 1 准备一个可以满足你需要的Linux服务器 2 安装工具 3 连接服务器 4 配置服务器 确保你已经完成第三步 成功连接上了服务器 1 安装Java 如
  • HDFS入门和应用开发场景案例:如何模拟实现分布式存储?

    如何解决海量数据存的下问题 1 传统式存储方式 应对文件存储服务 传统做法是在服务器上部署文件服务比如FTP 但是随着数据变多 会遇到存储瓶颈 此时 本能的操作反应是 内存不够加内存 磁盘不够加磁盘 单机纵向扩展 但是单机能够扩展的内存磁盘
  • 使用Python进行名片OCR(识别姓名,职务,电话,Email邮箱)

    上一篇博客介绍了如何通过以下方式自动OCR和扫描收据 检测输入图像中的接收 应用透视变换以获得收据的自顶向下视图 利用Tesseract对收据上的文本进行OCR 使用正则表达式提取价格数据 这篇博客将介绍如何使用Python对名片进行OCR
  • JAVA面试题 整合版

    1 List Set和Map 的区别 List 以索引来存取元素 有序的 元素是允许重复的 可以插入多个null Set 不能存放重复元素 无序的 只允许一个null Map 保存键值对映射 List 底层实现有数组 链表两种方式 Set
  • 无需MS Office!使用Aspose在C ++中以编程方式将 DOCX 转换为 DOC

    Microsoft Word 文档有两种格式 DOC 和 DOCX DOC 是一种较旧的格式 而 DOCX 是它的继任者 可以将 DOCX 文件转换为 DOC 格式 反之亦然 在本文中 将学习如何将 DOCX 文件转换为 DOC 格式以及如
  • Guava学习之Multisets

    今天谈谈Guava类库中的Multisets数据结构 虽然它不怎么经常用 但是还是有必要对它进行探讨 我们知道Java类库中的Set不能存放相同的元素 且里面的元素是无顺序的 而List是能存放相同的元素 而且是有顺序的 而今天要谈的Mul