# Java实现计数器 Counter

## 简单版本

```        HashMap<String,Integer> c = new HashMap<>();
stringList.forEach(per->{
c.put(per, c.getOrDefault(per, 0) + 1);//步骤1
});
return c;
}```

1. Integer是一个不可变的类,因此,在步骤1中发生了,取到当前数字,对其加一生成新的Integer对象,将这个对象放进map里面.频繁的创建中间对象,浪费.
2. 对于需要计数的每一个值,进行了两次map的操作,第一次获取其当前次数,第二次put加一之后的次数.

## 可变Integer

```    public static final class MutableInteger {
private int val;

public MutableInteger(int val) {
this.val = val;
}

public int get() {
return this.val;
}

public void set(int val) {
this.val = val;
}

public String toString() {
return Integer.toString(val);
}
}```

## 对map的操作减少

`HashMap``put`方法,其实是有返回值的,会返回旧值.

```    public static Map<String, MutableInteger> count2(List<String> strings) {
HashMap<String, MutableInteger> c = new HashMap<>();
strings.forEach(per -> {
MutableInteger init = new MutableInteger(1);
MutableInteger last = c.put(per, init);
if (last != null) {
init.set(last.get() + 1);
}
});
return c;
}```

## 简单测试一下:

```    public static void main(String[] args) {
List<String> list = new ArrayList<>();

String[] ss = {"my", "aa", "cc", "aa", "cc", "b", "w", "sssssa", "10", "10"};

for (int i = 0; i < 100000000; i++) {
}
long s = System.currentTimeMillis();
System.out.println(count1(list));
System.out.println(System.currentTimeMillis() - s);

long s1 = System.currentTimeMillis();
System.out.println(count2(list));
System.out.println(System.currentTimeMillis() - s1);

}```

```{aa=20000000, cc=20000000, b=10000000, w=10000000, sssssa=10000000, my=10000000, 10=20000000}
4234
{aa=20000000, cc=20000000, b=10000000, w=10000000, sssssa=10000000, my=10000000, 10=20000000}
951```

NOTE:

## 最终代码(使用泛型实现通用类)

• get(T): 返回该值目前的数量.
• getALl(): 返回该计数器目前所有的计数信息.形式为,`Map<T,Integer>`
```package daily.counter;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Created by pfliu on 2019/04/21.
*/
public class Counter<T extends Object> {

private HashMap<T, MutableInteger> c = new HashMap<>();

MutableInteger init = new MutableInteger(1);
MutableInteger last = c.put(t, init);
if (last != null) {
init.set(last.get() + 1);
}
}

}

public int get(T t) {
return c.get(t).val;
}

public Map<T, Integer> getAll() {
Map<T, Integer> ret = new HashMap<>();
c.forEach((key, value) -> ret.put(key, value.val));
return ret;
}

public static final class MutableInteger {

private int val;

MutableInteger(int val) {
this.val = val;
}

public int get() {
return this.val;
}

void set(int i) {
this.val = i;
}
}
}```

2019-04-22 完成

162 篇文章31 人订阅

0 条评论

## 相关文章

### Eureka 源码分析之 Eureka Client

Eureka是一种基于REST（Representational State Transfer）的服务，主要用于AWS云，用于定位服务，以实现中间层服务器的负载...

17030

21650

### Spring的JavaConfig

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

13750

48230

27040

38460

18740

48540

### HttpServletRequest 使用@Autowired 注解会有问题吗？

SpringBoot 中，默认注入的对象是单例对象，那么，我们如果注入一个 HttpServletRequest，会有问题吗？因为每次请求，Request 是不...

85350

### HttpClient参观记：.net core 2.2 对HttpClient到底做了神马

.net core 于 10月17日发布了 ASP.NET Core 2.2.0 -preview3，在这个版本中，我看到了一个很让我惊喜的新特性：HTTP C...

19720