本文共 2063 字,大约阅读时间需要 6 分钟。
每次循环都去检查Map中是否包含Key,如果包含则将原值+1再保存,如果不存在,则直接保存1.这种方式是最简单直接的一种方式,但是并不是最有效的方式,其低效的原因:
1、如果已经存在某个key(a),containsKey()和get()方法会扫描Map两次2、由于Integer是不可变对象,因此每次循环,都会创建一个新的对象放到Map中。
public void naiveCounter(String sArr[]) { HashMapcounter = new HashMap (); for (String a : sArr) { if (counter.containsKey(a)) { int oldValue = counter.get(a); counter.put(a, oldValue + 1); } else { counter.put(a, 1); } } }
自然可以想到创建一个可变的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) { HashMapnewCounter = new HashMap (); 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) { HashMapefficientCounter = new HashMap (); 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); } } }
转载地址:http://fwrxa.baihongyu.com/