JAVA学习Java 杂谈程序员

JAVA学习-Map详解

2017-06-05  本文已影响293人  遇见技术

1.介绍

Map接口定义了一个保存key-value的对象,该对象中key值是不存在重复的,每个key值至多对应一个value
在前面几篇的文章中分别介绍了Map的实现类,如HashMap、Hashtable、TreeMap,详细可以查看

2.类图结构

Map结构

如上图所示是实现Map接口的类图结构,主要包含了如下的类与接口:

3.比较

虽然HashMap、Hashtable、TreeMap这三个都是Map接口的实现,其内部实现及性能等还是存在区别,下面将从区别及性能两个方面去分析。

3.1 区别

3.1.1 基本
3.1.2 实现
3.1.3 内部原理
3.1.4 线程安全

3.2 性能

按照如下代码对HashMap、Hashtable、TreeMap的性能进行测试

public class HashMapProgress {
    //定义用于测试的HashMap
    private static HashMap<Integer,Integer> hashMap = new HashMap<>();
    //定义用于测试的Hashtable
    private static Hashtable<Integer,Integer> hashtable = new Hashtable<>();
    //定义用于测试的TreeMap
    private static TreeMap<Integer,Integer> treeMap = new TreeMap<>();

    /**
     * 添加元素的方法
     * @param map 对应的map
     * @param count 添加个数
     */
    public static void addEntry(Map<Integer,Integer> map, int count){
        Long startTime = System.currentTimeMillis();
        if (count <= 0){
            return;
        }
        for (int i = 0; i < count; i++) {
            map.put(i,i);
        }
        Long endTime = System.currentTimeMillis();
        System.out.println("添加(" + count + ")个元素使用时间:" + (endTime - startTime) + "s");
    }

    /**
     * 获取元素的方法
     * @param map
     * @param count
     */
    public static void getEntry(Map<Integer,Integer> map, int count){
        Long startTime = System.currentTimeMillis();
        if (count <= 0){
            return;
        }
        for (int i = 0; i < count; i++) {
            map.get(i);
        }
        Long endTime = System.currentTimeMillis();
        System.out.println("获取(" + count + ")个元素使用时间:" + (endTime - startTime) + "s");
    }

    public static void main(String[] args){
        System.out.println("-------HashMap测试开始-----");
        addEntry(hashMap,1000000);
        getEntry(hashMap,1000000);
        System.out.println("-------HashMap测试结束-----");

        System.out.println("-------Hashtable测试开始-----");
        addEntry(hashtable,1000000);
        getEntry(hashtable,1000000);
        System.out.println("-------Hashtable测试结束-----");

        System.out.println("-------TreeMap测试开始-----");
        addEntry(treeMap,1000000);
        getEntry(treeMap,1000000);
        System.out.println("-------TreeMap测试结束-----");
    }
}

分别测试了100000,1000000,10000000个数据的情况,测试结果如下所示:

数据量 HashMap Hashtable TreeMap
100000 插入用时:18s 查询用时:9s 插入用时:14s 查询用时:5s 插入用时:33s 查询用时:17s
1000000 插入用时:98s 查询用时:20s 插入用时:625s 查询用时:31s 插入用时:242s 查询用时: 145s
10000000 插入用时:9773s 查询用时:811s 插入用时:15055s 查询用时:3369s 插入用时:22354s 查询用时: 3889s

通过上表可以看出随着数据量的增加,时间变化差异还是很大的,而在单线程的情况下还是尽量使用HashMap,相对于Hashtable、TreeMap性能更好,而针对特定的情况需视情况而论。

4.总结

本文主要是对前面介绍的HashMap、Hashtable、TreeMap这些Map接口实现类的一个总结,主要分析这些实现类的一些特点以及存在的差异,最后想说的是针对不同的情况可以选择不同的Map进行编码,如有问题,望指正。

上一篇下一篇

猜你喜欢

热点阅读