在java中高效的计数器
在编程中,经常会用到HashMap作为计数器,本文简单介绍三种实现方式
第一种,最直观的计数器。
public void naiveCounter(String sArr[]) {
HashMap<String, Integer> counter = new HashMap<String, Integer>();
for (String a : sArr) {
if (counter.containsKey(a)) {
int oldValue = counter.get(a);
counter.put(a, oldValue + 1);
} else {
counter.put(a, 1);
}
}
}
在这种方式中,每次循环都去检查Map中是否包含Key,如果包含则将原值+1再保存,如果不存在,则直接保存1.这种方式是最简单直接的一种方式,但是并不是最有效的方式,其低效的原因:
1、如果已经存在某个key(a),containsKey()和get()方法会扫描Map两次
2、由于Integer是不可变对象,因此每次循环,都会创建一个新的对象放到Map中。
第二种,比较好的计数器
由于上述原因,自然可以想到创建一个可变的Integer对象,这样可以避免创建过多的Integer对象,
可变的Integer对象定义如下:
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;
} public String toString() {
return Integer.toString(val);
}
}
然后将上面的计数器优化一下,改成下面这张格式
public void betterCounter(String[] sArr) {
HashMap<String, MutableInteger> newCounter = new HashMap<String, MutableInteger>();
for (String a : sArr) {
if (newCounter.containsKey(a)) {
MutableInteger oldValue = newCounter.get(a);
oldValue.set(oldValue.get() + 1);
} else {
newCounter.put(a, new MutableInteger(1));
}
}
}
第三种,高效的计数器
上面第二种已经解决了创建过多Integer对象的问题,但是扫描两次Map,
其实在HashMap中,存在一个能够返回当前值的方法(HashMap.put(key,value)),
在上面的基础上,我们可以通过对原来的引用进行更新,而不必扫描两次Map
public void efficientCounter(String[] sArr) {
HashMap<String, MutableInteger> efficientCounter = new HashMap<String, MutableInteger>();
for (String a : sArr) {
MutableInteger initValue = new MutableInteger(1);
MutableInteger oldValue = efficientCounter.put(a, initValue);
//MutableInteger是可变的,此处只需判断之前是否为空,
// 如果非空,则更新MutableInteger的引用即可
if (oldValue != null) {
initValue.set(oldValue.get() + 1);
}
}
}
下面是经过500W次操作后,三者方法所消耗的时间
start test naiveCounter
end test naiveCounter,time is:5629
start test betterCounter
end test betterCounter,time is:5030
start test efficientCounter
end test efficientCounter,time is:4418
可以看出,最后一种确实是三种里面最高效的方式
在java中高效的计数器的更多相关文章
- 在 Java 中高效使用锁的技巧--转载
竞争锁是造成多线程应用程序性能瓶颈的主要原因 区分竞争锁和非竞争锁对性能的影响非常重要.如果一个锁自始至终只被一个线程使用,那么 JVM 有能力优化它带来的绝大部分损耗.如果一个锁被多个线程使用过,但 ...
- 七、如何在Java中高效检查一个数组是否含有一个值
如何检查一个数组(非排序的)是否包含特定的值.这是个非常有用或经常被在Java中使用.这是个在Stack Overflow中高得票的问题.在已经高得票的答案中,有许多不同的处理方法,但是时间的复杂度非 ...
- 161101、在Java中如何高效判断数组中是否包含某个元素
如何检查一个数组(无序)是否包含一个特定的值?这是一个在Java中经常用到的并且非常有用的操作.同时,这个问题在Stack Overflow中也是一个非常热门的问题.在投票比较高的几个答案中给出了几种 ...
- 在Java中如何高效的判断数组中是否包含某个元素
原文出处: hollischuang(@Hollis_Chuang) 如何检查一个数组(无序)是否包含一个特定的值?这是一个在Java中经常用到的并且非常有用的操作.同时,这个问题在Stack Ove ...
- 在Java中怎样高效的推断数组中是否包括某个元素
来自 http://www.hollischuang.com/archives/1269? 怎样检查一个数组(无序)是否包括一个特定的值?这是一个在Java中经经常使用到的并且非常实用的操作.同一时候 ...
- 在java中构建高效的结果缓存
文章目录 使用HashMap 使用ConcurrentHashMap FutureTask 在java中构建高效的结果缓存 缓存是现代应用服务器中非常常用的组件.除了第三方缓存以外,我们通常也需要在j ...
- 在Java中如何高效判断数组中是否包含某个元素
如何检查一个数组(无序)是否包含一个特定的值?这是一个在Java中经常用到的并且非常有用的操作.同时,这个问题在Stack Overflow中也是一个非常热门的问题.在投票比较高的几个答案中给出了几种 ...
- Java中的GC操作及相关概念
一.GC Roots Tracing的基本思路:通过一系列名为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所经过的路径称为引用链(Reference Chai ...
- 面试中关于Java中涉及到知识点(转)
本篇文章会对面试中常遇到的Java技术点进行全面深入的总结,帮助我们在面试中更加得心应手,不参加面试的同学也能够借此机会梳理一下自己的知识体系,进行查漏补缺. 1. Java中的原始数据类型都有哪些, ...
随机推荐
- oracle----复制表中的数据
两种方法: 1. 在创建表的时候将数据从其他表中复制过来(并且表的结构也复制过来): 语法: CREATE TABLE table_name AS SELECT column1,......|* FR ...
- IIS的Unicode漏洞攻击
IIS有十多种常见漏洞,但利用得最多的莫过于Unicode解析错误漏洞.微软IIS 4.0/5.0在Unicode字符解码的实现中存在一个安全漏洞,用户可以远程通过IIS执行任意命令.当IIS打开文件 ...
- MySQL注入中load_file()函数的应用
常用的一些Load_File()函数攻击手法:
- 《php和mysql web开发》读书笔记
总算是强迫自己把第一篇给看完了,在这里做一个小结,将一些知识点记录下来. 一.第一篇 使用PHP 1.php中的注释.php支持c.c++和shell脚本风格注释 /**/多行注释 //单行注释 ...
- (重)POJ 3020Antenna Placement
http://poj.org/problem?id=3020 呃...这个题不是很会,所以找了大神的博客做了参考,说得很详细 http://blog.csdn.net/lyy289065406/art ...
- html5 高级动画精灵
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- Linux kernel ‘aac_send_raw_srb’函数输入验证漏洞
漏洞名称: Linux kernel ‘aac_send_raw_srb’函数输入验证漏洞 CNNVD编号: CNNVD-201311-422 发布时间: 2013-11-29 更新时间: 2013- ...
- 对 Azure Backup 的常见配置问题进行故障排除
Giridhar Mosay云 + Enterprise 项目经理 这篇博客文章有助于解决 Microsoft云备份解决方案(即 Azure Backup)的常见配置问题.客户通常会在安装或注册 ...
- 处理MVC中默认的Json方法返回时间的问题
利用 Json方法返回 数据时,如果有时间格式,会变成 "\/Date(1369419656217)\/" 这个样子,问了同事找到个解决方法 using Newtonsoft.Js ...
- acm位运算应用 搜索
acm位运算应用 搜索 搜索 此处不讲题目,只讲位运算是怎样在这些题中实现和应用的.由于搜索题往往是基于对状态的操作,位运算往往特别有效,优化之后的效果可以有目共睹. 例1.POJ 132 ...