您的位置:首页 > 职场人生

黑马程序员_java高效计数器

2013-11-09 19:48 549 查看
-------
android培训java培训、期待与您交流! ----------

你可能经常使用HashMap作为一个计数器来理解频率的东西从数据库或文本。本文比较了3种不同的方法来实现计数器使用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);

}

}

在每个循环,你检查是否存在与否的关键。如果是,增加旧值1,如果不是,将它设置为1。该方法简单、直观,但它不是最有效的方法。这种方法被认为是低效率的原因如下:

>>containsKey(),get()被称为两次当一个键已经存在。这意味着搜索地图两次。

>>因为整数是不可变的,每个循环将创建一个新的一个增量的旧值

2、更好的计数器

我们想要一个可变的整数自然避免创建许多整数对象。一个可变的整数类定义如下:

这似乎是更好的,因为它不需要创建许多整数对象了。然而,搜索仍是两次在每个循环如果一个关键的存在。

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));

}

}

3、高效的计数器

这个HashMap。把(key,value)方法返回当前的价值的关键。这是有用的,因为我们可以使用参考旧的值来更新值没有搜索一个更多的时间!

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);

}

}

4、性能差异

测试性能的三种不同的方法,使用以下代码。性能测试是在100万次。原始的结果如下:

Naive Approach : 222796000

Better Approach: 117283000

Efficient Approach: 96374000

不同的是重要的- 223与117和96。有很多区别,比较幼稚,这表明创建对象是昂贵的!

String s = "one two three two three three";

String[] sArr = s.split(" ");

long startTime = 0;

long endTime = 0;

long duration = 0;

// naive approach

startTime = System.nanoTime();

HashMap<String, Integer> counter = new HashMap<String, Integer>();

for (int i = 0; i < 1000000; i++)

for (String a : sArr) {

if (counter.containsKey(a)) {

int oldValue = counter.get(a);

counter.put(a, oldValue + 1);

} else {

counter.put(a, 1);

}

}

endTime = System.nanoTime();

duration = endTime - startTime;

System.out.println("Naive Approach : " + duration);

// better approach

startTime = System.nanoTime();

HashMap<String, MutableInteger> newCounter = new HashMap<String, MutableInteger>();

for (int i = 0; i < 1000000; i++)

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));

}

}

endTime = System.nanoTime();

duration = endTime - startTime;

System.out.println("Better Approach: " + duration);

// efficient approach

startTime = System.nanoTime();

HashMap<String, MutableInteger> efficientCounter = new HashMap<String, MutableInteger>();

for (int i = 0; i < 1000000; i++)

for (String a : sArr) {

MutableInteger initValue = new MutableInteger(1);

MutableInteger oldValue = efficientCounter.put(a, initValue);

if (oldValue != null) {

initValue.set(oldValue.get() + 1);

}

}

endTime = System.nanoTime();

duration = endTime - startTime;

System.out.println("Efficient Approach: " + duration);

当你使用一个计数器,你可能还需要一个函数来进行地图的价值。你可以查看常用方法的HashMap。

-------
android培训java培训、期待与您交流! ----------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: