用Java递增Map值的最有效方法–仅搜索一次键

这个问题可能被认为太基础了,但是在论坛上经常被问到。 在本文中,我将讨论一种仅在Map ONCE中搜索键的方法。

让我们首先来看一个例子。 假设我正在使用Map创建一个字符串频率列表,其中每个键是一个正在计数的String ,值是一个Integer ,每次添加一个String都会递增。 实现它的一种直接方法是

int count = map.containsKey(string) ? map.get(string) : 0;
map.put(string, count + 1);

这段代码运行很慢,因为它在地图上包含三个潜在的昂贵操作,即containsKey()get()[put()](http://docs.oracle.com/javase/7/docs/ api / java / util / Map.html#put(K,V)) 。 每个都需要在地图中搜索关键字。 现在,让我们重构代码以获得更好的性能。

整数与MutableInteger与AtomicInteger

我们必须调用三个昂贵的操作的重要原因之一是使用Integer进行计数。 在Java中, Integer不可变的 。 它阻止我们在构造后修改整数值。 因此,要增加一个计数器,我们必须首先从映射中获取整数,然后通过添加一个整数来创建另一个新整数,然后将其放回映射中。

为了使计数器可变,有几种方法。 一种是简单地创建自己的MutableInteger ,就像我在下面显示的那样。

public class MutableInteger {private int val;public MutableInteger(int val) {this.val = val;}public int get() {return val;}public void set(int val) {this.val = val;}
}

另一种方法可能是在Java中使用AtomicInteger ,该方法用于原子增量计数器等应用程序中。 但是AtomicInteger的主要选择是如果您希望通过对整数进行操作来实现线程安全。 因此,它不能用作Integer的替代。 基于此,如果您的项目不是线程安全性的重要考虑因素,则我不建议您使用AtomicInteger

仅搜索一次密钥

使用MutableInteger之后 ,我们可以将上面的代码更改为

if (map.containsKey(string)) {MutableInteger count = map.get(string);count.set(count.get() + 1);
} else {map.put(string, new MutableInteger(1));
}

要么

MutableInteger count = map.get(string);
if (count != null) {count.set(count.get() + 1);
} else {map.put(string, new MutableInteger(1));
}

在最坏的情况下,如果以前没有看到过密钥,则代码将搜索密钥两次:一次用于检索,一次用于设置。 它比上一个要好得多。 但是我们不应该立即满足并停止。 如果您在Java文档中选中了[Map.put()](http://docs.oracle.com/javase/7/docs/api/java/util/Map.html#put(K,V))方法,您会发现此方法将返回the previous value associated with key 。 这意味着我们可以将检索和设置合并为一个。 但是,您可能想知道:如果不首先检索计数器,如何设置新计数器? 现在,我们终于可以触摸本文中最棘手的部分:我们可以简化放置零频率计数器的工作!

public int incrementCount(K key, int count) {MutableInteger tmpCount = new MutableInteger(0);MutableInteger oldCount = map.put(key, tmpCount);if (oldCount != null) {count += oldCount.get();}tmpCount.set(count);return count;}

另一个柜台

看起来将所有必要的操作放入一个类中将对将来的使用有所帮助。 因此,我创建了一个称为Counter的类并将其公开。 计数器定义一个集合,该集合对对象出现在集合中的次数进行计数。 假设您有一个包含{a, a, b, c}的Counter。 在“ a”上调用getCount()将返回2,而在keySet()上调用将返回{a, b, c} 。 此类的工作方式类似于Map ,但是具有不同的方法来轻松获取/设置/增加对象的计数以及使用该计数来计算各种函数。 Counter构造函数和addAll()方法可用于复制另一个Counter的内容。 根据IntCounterAbstractMapBag修改Counter类。

Counter上的一些突出操作包括

  • gainCount()decrementCount() :将给定键的给定计数加/减到当前计数中。 如果之前没有看到该键,则假定它的计数为0,因此增量方法会将其计数设置为给定的数量。 减量会将其计数设置为-1。
  • getCount() :返回给定键的当前计数,如果以前没有看到过,则返回0。
  • keysAt()keysAbove()keysBelow() :返回其计数在给定阈值之上,之下或之下的一组键。 该集合可能包含0个元素,但不会为null。
  • argmin ()argmax() :找到并返回此Counter中具有最小/最大计数的密钥。 如果有几个最小/最大计数,则返回随机值。 如果此Counter为空,则返回null。

参考: 在Java中增加Map值的最有效方法–只需从PGuru博客的JCG合作伙伴 Peng Yifan那里 搜索一次密钥 。

翻译自: https://www.javacodegeeks.com/2013/10/most-efficient-way-to-increment-a-map-value-in-java-only-search-the-key-once.html

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

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

相关文章

[译] 帮助你成为一名成功的 Web 开发工程师的 21 步

前言 随着 Web 开发的蓬勃发展,许多人都在问这样一个问题:我如何才能成为一名 Web 开发者?我认为这个问题不应该这样问,而应该是:我如何才能成为一名成功的 Web 开发者?这样的问题是很有必要的,…

小白_Unity引擎_Mathf

Ceil 1 //向上取值,向大取值 2 Debug.Log(Mathf.Ceil(0.1f)); //1 3 Debug.Log(Mathf.Ceil(0.9f));//1 4 Debug.Log(Mathf.Ceil(-0.1f));//0 5 Debug.Log(Mathf.Ceil(-0.9f));//0 Floor 1 //向下取值,向…

循环卷积和周期卷积的关系_基于单口RAM读写的卷积电路(下)

这是迟到很久的卷积电路verilog设计的下篇。。。你看我还有机会吗。。。上回我们给出系统的层次结构、卷积计算模块以及用于数据缓存的fifo模块,今天我们首先回顾一下上一次的关键内容。系统结构回顾RTL代码文件可以分为结构如下所示 ~|--top_conv_tb.v|--top_conv.…

浅析 PHP 中的 Generator

浅析 PHP 中的 Generator Miss Wang php开发案例 前天 何为 Generator 从 PHP 5.5 开始,PHP 加入了一个新的特性,那就是 Generator,中文译为生成器。生成器可以简单地用来实现对象的迭代,让我们先从官方的一个小例子说起。 xrange…

哈师大计算机等级考试,哈尔滨师范大学教务处

阳光高考网 小编整理分享http://jwc.hrbnu.edu.cn/哈尔滨师范大学教务处教务管理系统 哈尔滨师范大学教务平台 学校前身是1946年我党在东北解放区建立..点击查看http://jwc.hrbnu.edu.cn/哈尔滨师范大学教务处教务管理系统 重点支持建设的百所中西部高校之一。http://www.17xue…

Spring MVC应用程序中的Thymeleaf模板布局,无扩展

在使用JSP / JSTL和Apache Tiles几年之后,我开始为我的Spring MVC应用程序发现Thymeleaf。 Thymeleaf是一个非常出色的视图引擎,尽管目前缺乏良好的IntelliJ(投票:http: //youtrack.jetbrains.com/issue/IDEABKL-6713 &#xff09…

注意安全!XSS 和 XSRF

[Tips] 本文是从 jianshu 平台重新修改编辑后移植来的,比上一版本做了些修订。 最近在看一些关于网络安全的问题,当然许多是跟前端相关的,包括且不局限于xss和xsrf 了,那么小编就结合最近的学习实践谈一些粗浅的认识。&#xff08…

go分析和kegg分析_干货预警:3分钟搞定GO/KEGG功能富集分析(2)

在 3分钟了解GO/KEGG功能富集分析 一文中给大家讲解了GO和KEGG的基本概念和内涵,并且给大家介绍了DAVID这一神奇网站。今天我们就把GO/KEGG功能富集分析的详细教程按部就班地呈现给大家,有请小猎豹。 多图预警,轻点图片,查看高清大图 1 Step1: 打开DAVID官网:https://dav…

区块链即将面临的问题有哪些?

很多人只知道区块链给我们带来的好处,但在这个技术和行业高速发展的阶段,区块链也出现了一些问题,那么区块链即将面临的问题有哪些?有哪些问题会对区块链行业的发展产生非常不利的影响呢?下面我来给大家说说区块链发展…

如何在Java中读取CSV文件-Iterator和Decorator的案例研究

在本文中,我将讨论如何使用Apache Common CSV读取CSV(逗号分隔值)文件。 从这个案例研究中,我们将学习如何在设计模式的上下文中使用Iterator和Decorator来提高不同情况下的可重用性。 但是在开始之前,我想我必须先回答…

如何在本地开发环境调试微信 JS-SDK

以下篇幅将会描述不同前提下对应的调试策略,当然也有可能不是最优解,望斧正 →_→ 前言 何谓「安全域名限制」? 以微信 JS-SDK 的使用为例,每个公众号被限制最多可设置三个安全域名,且必须能被腾讯服务器所验证&#…

PHP中常用加解密方式

PHP中使用OpenSSL生成RSA公钥私钥及进行加密解密示例 加密基础 加密算法一般分为两种:对称加密算法和非对称加密算法。 对称加密 对称加密算法是消息发送者和接收者使用同一个密匙,发送者使用密匙加密了文件,接收者使用同样的密匙解密&#x…

云南省农村信用社计算机岗位待遇如何,云南农村信用社薪资待遇如何?

在云南如果去存钱,相信大多数人都会把自己的小钱钱存在农村信用社而不是XX银行。在这一块风景秀丽,人美山美水美的地方,就金融行业来说云南农村信用社要是说自己差,那基本没有谁敢说自己做的好。所以在云南农信社这家企业里做一名…

小票上为啥指甲能划出印_指甲上出现竖纹,除遗传问题,或是身体在向你拉警报了,别忽视...

生活中常见女生给指甲抹上各种不同的颜色来让它变得美美的,指甲起着修饰人的形象的作用。而指甲的状况也能折射出身体的健康状态如何。每个人的指甲形态不一,有的润滑饱满,光滑平整,有月牙;有的坑坑洼洼,凸…

require.context

带表达式的 require 语句 如果你的 require参数含有表达式(expressions),会创建一个上下文(context),因为在编译时(compile time)并不清楚具体是哪一个模块被导入 require("./template/" name ".ejs");webpack 解析 require() 的…

使用JSF 2.2功能来开发可滚动,可延迟加载的Ajax数据表

这次,我想与您分享我最近从JSF 2.2功能中学到的知识。 为此,我决定创建一个简单的ajax,可滚动的延迟加载数据表。 请注意, 绝不这是相当大的库如Primefaces , RichFaces的或ICEFaces的 。 这只是为了告诉您我学到了什…

如何监视ps/查询的性能和使用

可以使用“查询管理”页面监视查询性能和使用情况。您可以获得的一些统计信息包括平均运行时、运行次数和上次运行日期。使用预定义的搜索,还可以选择要检查和报告的查询。查询管理还允许您取消当前在查询管理器和查询查看器中运行的查询,以及启用和禁用…

金融计算机怎么调成链式,FRM金融计算器使用方法

2020FRM考试计算器:想一想FRM一级考试基本上按计算器停不下来,我们就一定要买一个简单易操作的计算器,但是GARP对于FRM考生所使用的计算器是有规定的:所有参加FRM考试的考生必须使用GARP指定的计算器,如果考生在考试期…

spring 基础

作者:Spring太难链接:https://zhuanlan.zhihu.com/p/38131490来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。目录 Spring 概述 依赖注入 Spring beans Spring注解 Spring数据访问 Spring面向切面…

参数调优为什么要采样_程序员精进之路:性能调优利器--火焰图

本文主要分享火焰图使用技巧,介绍 systemtap 的原理机制,如何使用火焰图快速定位性能问题原因,同时加深对 systemtap 的理解。让我们回想一下,曾经作为编程新手的我们是如何调优程序的?通常是在没有数据的情况下依靠主…