HashMap计数方法优化

大家可能经常会用HashMap来计算数据库或文本中某些特定内容出现的频率,这篇文章比较了三种HashMap计数器的实现方法,大家可做个参考。

1、首先介绍最基础的一种实现方式,代码如下
String s = "one two three two three three";
String[] sArr = s.split(" ");
 
//naive approach	 
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);
	}
}
这种实现方法中,每次循环遍历都要检查key存在与否,不存在表明第一次出现,设置对应的value值为1,如果存在,则给value值加1。这种方法简单而直观,但它并不是一个很好的实现方式,因为它没有考虑到以下两种情况所造成的效率不高的问题:
1、1  当Key存在的时候,方法containsKey()和方法get()会对map循环两次
1、2  因为Integer类型是不可变的,所以每次给value值加1操作的时候都会创建一个新的Integer对象

2、较好一点的一个实现方式,解决了上述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;
	}
 
	//used to print value convinently
	public String toString(){
		return Integer.toString(val);
	}
}

这样我们的代码就可以优化为:
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对象,所以较第一种方法要好一些,但是key存在时依然循环遍历两次。所以我们需要进一步的进行优化。

3、最有效的实现方式

HashMap<String, MutableInteger> efficientCounter = new HashMap<String, MutableInteger>();
 
for (String a : sArr) {
	MutableInteger initValue = new MutableInteger(1);
	MutableInteger oldValue = efficientCounter.put(a, initValue);
 
	if(oldValue != null){
		initValue.set(oldValue.get() + 1);
	}
}

因为HashMap.put(key, value)这个方法返回的是key的当前值,即当前key对应的value,所以我们可以利用value的索引来对其进行加1操作,一次搞定,不必在去查找浪费性能!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值