Java 使用Map作计数器

   很多时候我们需要对一些高频出现的词汇或……做统计。使用一个map集合很容易就能做到这一点,那么怎样做才能做高效呢?举几个例子说明:

如:从数据库读取数据或从文本文件中读取数据,统计某些字符出现的次数

//统计str中one、two、three出现的次数
String str = "one two three two three three";

HashMap<String, Integer> counter1 = new HashMap<String, Integer>();		
for (String a : sArr) {
    if (counter1.containsKey(a)) {
        int oldValue = counter1.get(a);
        counter1.put(a, oldValue + 1);
    } else {
        counter1.put(a, 1);
    }
}

上面的计数器是能满足要求的,但是它并不是最高效的,有两点原因:

1、Integer就像String一样是不可变的类型,计数每次增长都要重新创建一个Integer对象;

2、当统计次数大于一时,要使用containsKey(),get(),也就是说要从map集合中搜索两次;

    从1入手改进下计数器,可以自定义一个类用来计数,如:

class customInt{
    private int ct;
    public customInt(int ct){
        this.ct = ct;
    }
    
    public void setCt(int ct){
        this.ct = ct;
    }
    
    public int getCt(){
        return ct;
    }
}

HashMap<String, customInt> counter2 = new HashMap<String, customInt>();		
for (String a : sArr) {
    if (counter2.containsKey(a)) {
        customInt oldVal = counter2.get(a);
        oldVal.setCt(oldVal.getCt() + 1);
    } else {
        counter2.put(a, new customInt(1));
    }
}

//counter1和counter2 两次的输出(根据计算机以及搜索内容的不同输出结果肯定会有差异,但counter2耗时比counter1少):

结果很明显改进后的计数器明显比最初的高效,根据上面说到的两点对计数器效率的影响,再次对计数器进行改进优化。查API可知Map集合的put()方法,会返回与key相关联的旧值,没有则返回null(API:the previous value associated with key, or null if there was no mapping for key.)。对计数器再进行修改:

HashMap<String, customInt> counter3 = new HashMap<String, customInt>();		
for (String a : sArr) {
    customInt initInt = new customInt(1);
    customInt oldVal = counter3.put(a, initInt);
    if (oldVal != null) {
       initInt.setCt(oldVal.getCt() + 1);
    }
}

    当然关于map集合作计数器的实现还有有很多其他的方式,例如:

HashMap<String, customInt> counter4 = new HashMap<String, customInt>();		
for (String a : sArr) {
    customInt val = counter4.get(a); 		
    if (val != null) {
	val.setCt(val.getCt() + 1);
    } else {
	counter4.put(a, new customInt(1));
    }
}
//或者是使用int[]、AtomicInteger等来计数,都可以
HashMap<String, int[]> counter5 = new HashMap<String, int[]>();		
for (String a : sArr) {
    int[] val = counter5.get(a); 		
    if (val != null) {
	val[0]++;
    } else {
	counter5.put(a, new int[]{1});
    }
}

HashMap<String, AtomicInteger> counter6 = new HashMap<String, AtomicInteger>();		
for (String a : sArr) {
    AtomicInteger val = counter6.get(a); 		
    if (val != null) {
	val.incrementAndGet();
    } else {
	counter6.put(a, new AtomicInteger(1));
    }
}

以上是使用map集合实现几种计数器,究竟哪种效率最高,可能会因搜索数据量,统计事物出现的频率,计算机等因素有所不同,根据我个人的实验,使用int[ ](counter5)最为高效。

     有兴趣的可以自己测验试试。记得砖块捡小的拍哦……

转载于:https://my.oschina.net/youruci/blog/339662

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值