HashMap计数器的高效实现
来源:互联网 发布:java常用的容器 编辑:程序博客网 时间:2024/06/05 16:50
原始的计数器
在实际应用中,我们经常把HashMap作为一个计数器使用.例如统计一篇文章中单词 'the' 出现了多少次.于是我们很轻松地就能写出下面的程序:
Map<String, Integer> counter = new HashMap<String, Integer>();for(String s : strs) {if(counter.containsKey(s)) {Integer times = counter.get(s);times = times + 1;} else {counter.put(s, 1);}}
这个计数器确实可以完成我们所需的功能,但在速度上却慢了点.仔细分析不难发现,由于Integer是immutable的,即不可变的,所以在执行times = times + 1这行代码时实际上会创建一个新的Integer对象,然后再赋给times.这样一来,每次将次数 +1 时都会创建一个Integer,等循环执行完内存中可能会存在成千上万个垃圾Integer对象.所以,如果能将不可变的Integer改成可变的(mutable),能提高程序性能.
改进后的计数器
我们可以自己定义一个名为MutableInteger 的类来实现可变:
class MutableInteger {int value;public MutableInteger(int val) {this.value = val;}public int getValue() {return value;}public void setValue(int value) {this.value = value;}}
改进后的程序代码如下:
Map<String, MutableInteger> counter = new HashMap<String, MutableInteger>();for(String s : strs) {if(counter.containsKey(s)) {MutableInteger times = counter.get(s);times.setValue(times.getValue() + 1); // 不会每次都创建新对象了} else {counter.put(s, new MutableInteger(1));}}
高效的计数器
代码如下:
Map<String, MutableInteger> counter = new HashMap<String, MutableInteger>();for(String s : strs) {MutableInteger newValue = new MutableInteger(1);MutableInteger oldValue = counter.put(s, newValue);if(null != oldValue) {newValue.setValue(oldValue.getValue() + 1);}}
这段代码看进来好像有些不好理解,我们来分析一下:
1. 执行
MutableInteger newValue = new MutableInteger(1);
时,会创建一个新的MutableInteger对象,初始化为1.
2. 执行
MutableInteger oldValue = counter.put(s, newValue);
时,程序会将刚刚创建的newValue放到HashMap中,同时返回执行完put()方法之后当前的健所对应的值.
3. 如果oldValue为不为空,则说明原来的HashMap中没有这个键.而此时我们已经将没有的键put进去了,且其对应的值恰好是newValue所引用的对象.因此我们只需要通过newValue调用setValue()方法就能修改到值了.
我编写了一个测试程序,对这3个counter进行了性能对比,结果如下:
大概是8 : 7 : 6.
- HashMap计数器的高效实现
- Java实现的高效计数器
- 关于如何用java实现一个高效的计数器
- Java基础高效复习(hashmap的实现原理)
- 一个高效的C++性能计数器模板
- 在java中高效的计数器
- 简单安全高效的Java计数器
- 计数器的实现
- lua中高效的HashMap
- Java高效计数器
- Java高效计数器
- Java高效计数器
- Java HaspMap高效计数器
- php实现简单的计数器
- jquery实现的网页计数器
- CountView类似计数器的实现
- 一个易用,高效,精确的纳秒级C#时间计数器
- entrySet最高效的遍历hashmap
- eclipse debug 重新指定源码
- 32位Win7下安装与配置PHP环境
- 动态可扩展哈希表的实现--第一集
- dsp--28335的cmd文件学习(二)
- 一张图一个例子让你看懂AOP
- HashMap计数器的高效实现
- NodeJS 安装mongoose(备忘)
- hdu 2197 本原串(容斥定理)
- Ni Kang Ni Kang
- Linux设备驱动--linux RTC 驱动模型分析
- ng Baidu Baidu Baidu ang
- 当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针!
- 杭电ACM hdu 1398 Square Coins 解题报告(母函数)
- uddenly