java map的正确姿势,你还再new HashMap么?

63 阅读2分钟

java map的正确姿势,你还再new HashMap么?

先看示例

反例

	Map<String, Object> paramMap = new HashMap<>(2);
	paramMap.put("deviceId", "324sefdsfds2342ersdfsdf");
	paramMap.put("number","13800138000");
	Map resultMap = httpClientUtil.doPost(braceletIPPort + "/iot/bracelet/", paramMap);

正例,使用guava初始化

 <!--guava类库依赖 -->
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>18.0</version>
    </dependency>
	import com.google.common.collect.Maps;
	#使用google guava工具初始化
	Map<String, Object> paramMap = Maps.newHashMapWithExpectedSize(2);
	paramMap.put("deviceId", "324sefdsfds2342ersdfsdf");
	paramMap.put("number","13800138000");
	Map resultMap = httpClientUtil.doPost(braceletIPPort + "/iot/bracelet/", paramMap);

为什么呢?

HashMap 初始化指定capacity后,当增加后并不是到指定capacity后,才扩容。 本例中指定HashMap的capacity =2,当paramMap.put("number","13800138000")时候执行了扩容,带来cpu损耗。 guava初始的capacity 直接初始化足够的空间,避免了,增长后的扩容带来的损耗。

总结:

使用hashmap不是不行,只是最好根据扩容机制自己计算一下capacity 参数。而guava自动帮你计算好了,直接使用即可。 小的项目怎么写都无所谓了,但是tps高的应用,效果好使很明显的。

测试用例

用于Map 并没有直接获取capacity 的方法,所以采用java反射获取capacity

public class MapLean {
    public static void main(String[] args) {

        Map map = new HashMap<>(2);
        Map map2 = Maps.newHashMapWithExpectedSize(2);

        MapLean.getCapactiy(map, "map1初始化size=");
        MapLean.getCapactiy2(map2, "map2初始化size=");
        for (int i = 1; i <= 2; i++) {
            map.put(i, "" + i);
            MapLean.getCapactiy(map, "map1循环第" + i + "次:");
            map2.put(i, "" + i);
            MapLean.getCapactiy2(map2, "map2循环第" + i + "次:");
        }
    }

    @SneakyThrows
    private static Object getCapactiy(Map map, String message) {
        Class<?> mapType = map.getClass();
        Method capacity = mapType.getDeclaredMethod("capacity");
        capacity.setAccessible(true);
        Object capacityObject = capacity.invoke(map);
        System.out.println(message + capacityObject);
        return capacityObject;
    }

    @SneakyThrows
    private static Object getCapactiy2(Map map, String message) {
        Class<?> mapType = map.getClass();
        Method capacity = mapType.getDeclaredMethod("capacity");
        capacity.setAccessible(true);
        Object capacityObject = capacity.invoke(map);
        System.out.println(message + capacityObject);
        return capacityObject;
    }
}
执行结果:
map1初始化size=2
map2初始化size=4
map1循环第1次:2
map2循环第1次:4
map1循环第2次:4
map2循环第2次:4