Java map 详解用法、遍历、排序、常用API等

2022年6月10日09:08:19

Map用法

类型介绍

Java 自带了各种 Map 类,这些 Map 类可归为三种类型:

通用Map

用于在应用程序中管理映射,通常在 java.util 程序包中实现 HashMap、Hashtable、Properties、LinkedHashMap、IdentityHashMap、TreeMap、WeakHashMap、ConcurrentHashMap

专用Map

通常我们不必亲自创建此类Map,而是通过某些其他类对其进行访问java.util.jar.Attributesjavax.print.attribute.standard.PrinterStateReasonsjava.security.Providerjava.awt.RenderingHintsjavax.swing.UIDefaults

自行实现Map

一个用于帮助我们实现自己的Map类的抽象类 AbstractMap

类型区别

HashMap

最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null(多条会覆盖);允许多条记录的值为 Null。非同步的。

TreeMap

能够把它保存的记录根据键(key)排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。

Hashtable

与 HashMap类似,不同的是:key和value的值均不允许为null;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。

LinkedHashMap

保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。

Map 初始化

Map<String, String> map=newHashMap<String, String>();

插入元素

map.put("key1","value1");

获取元素

map.get("key1")

移除元素

map.remove("key1");

清空map

map.clear();

四种常用Map插入与读取性能比较

插入10次平均(ms)

1W 10W 100W
HashMap 56 261 3030
LinkedHashMap 25 229 3069
TreeMap 29 295 4117
Hashtable 24 234 3275

读取10次平均(ms)

1W 10W 100W
HashMap 2 21 220
LinkedHashMap 2 20 216
TreeMap 5 103 1446
Hashtable 2 22 259

测试代码

package net.xsoftlab.baike;import java.util.HashMap;import java.util.Hashtable;import java.util.LinkedHashMap;import java.util.Map;import java.util.Random;import java.util.TreeMap;import java.util.UUID;publicclassTest{staticint hashMapW=0;staticint hashMapR=0;staticint linkMapW=0;staticint linkMapR=0;staticint treeMapW=0;staticint treeMapR=0;staticint hashTableW=0;staticint hashTableR=0;publicstaticvoidmain(String[] args){for(int i=0; i<10; i++){
            Test test=newTest();
            test.test(100*10000);
            System.out.println();}
        System.out.println("hashMapW = "+ hashMapW/10);
        System.out.println("hashMapR = "+ hashMapR/10);
        System.out.println("linkMapW = "+ linkMapW/10);
        System.out.println("linkMapR = "+ linkMapR/10);
        System.out.println("treeMapW = "+ treeMapW/10);
        System.out.println("treeMapR = "+ treeMapR/10);
        System.out.println("hashTableW = "+ hashTableW/10);
        System.out.println("hashTableR = "+ hashTableR/10);}publicvoidtest(int size){int index;
        Random random=newRandom();
        String[] key=newString[size];// HashMap 插入
        Map<String, String> map=newHashMap<String, String>();long start= System.currentTimeMillis();for(int i=0; i< size; i++){
            key[i]= UUID.randomUUID().toString();
            map.put(key[i], UUID.randomUUID().toString());}long end= System.currentTimeMillis();
        hashMapW+=(end- start);
        System.out.println("HashMap插入耗时 = "+(end- start)+" ms");// HashMap 读取
        start= System.currentTimeMillis();for(int i=0; i< size; i++){
            index= random.nextInt(size);
            map.get(key[index]);}
        end= System.currentTimeMillis();
        hashMapR+=(end- start);
        System.out.println("HashMap读取耗时 = "+(end- start)+" ms");// LinkedHashMap 插入
        map=newLinkedHashMap<String, String>();
        start= System.currentTimeMillis();for(int i=0; i< size; i++){
            key[i]= UUID.randomUUID().toString();
            map.put(key[i], UUID.randomUUID().toString());}
        end= System.currentTimeMillis();
        linkMapW+=(end- start);
        System.out.println("LinkedHashMap插入耗时 = "+(end- start)+" ms");// LinkedHashMap 读取
        start= System.currentTimeMillis();for(int i=0; i< size; i++){
            index= random.nextInt(size);
            map.get(key[index]);}
        end= System.currentTimeMillis();
        linkMapR+=(end- start);
        System.out.println("LinkedHashMap读取耗时 = "+(end- start)+" ms");// TreeMap 插入
        key=newString[size];
        map=newTreeMap<String, String>();
        start= System.currentTimeMillis();for(int i=0; i< size; i++){
            key[i]= UUID.randomUUID().toString();
            map.put(key[i], UUID.randomUUID().toString());}
        end= System.currentTimeMillis();
        treeMapW+=(end- start);
        System.out.println("TreeMap插入耗时 = "+(end- start)+" ms");// TreeMap 读取
        start= System.currentTimeMillis();for(int i=0; i< size; i++){
            index= random.nextInt(size);
            map.get(key[index]);}
        end= System.currentTimeMillis();
        treeMapR+=(end- start);
        System.out.println("TreeMap读取耗时 = "+(end- start)+" ms");// Hashtable 插入
        key=newString[size];
        map=newHashtable<String, String>();
        start= System.currentTimeMillis();for(int i=0; i< size; i++){
            key[i]= UUID.randomUUID().toString();
            map.put(key[i], UUID.randomUUID().toString());}
        end= System.currentTimeMillis();
        hashTableW+=(end- start);
        System.out.println("Hashtable插入耗时 = "+(end- start)+" ms");// Hashtable 读取
        start= System.currentTimeMillis();for(int i=0; i< size; i++){
            index= random.nextInt(size);
            map.get(key[index]);}
        end= System.currentTimeMillis();
        hashTableR+=(end- start);
        System.out.println("Hashtable读取耗时 = "+(end- start)+" ms");}}

Map 遍历

初始化数据

Map<String, String> map=newHashMap<String, String>();
map.put("key1","value1");
map.put("key2","value2");

增强for循环遍历

使用keySet()遍历

for(String key: map.keySet()){
    System.out.println(key+" :"+ map.get(key));}

使用entrySet()遍历

for(Map.Entry<String, String> entry: map.entrySet()){
    System.out.println(entry.getKey()+" :"+ entry.getValue());}

迭代器遍历

使用keySet()遍历

Iterator<String> iterator= map.keySet().iterator();while(iterator.hasNext()){
    String key= iterator.next();
    System.out.println(key+" :"+ map.get(key));}

使用entrySet()遍历

Iterator<Map.Entry<String, String>> iterator= map.entrySet().iterator();while(iterator.hasNext()){
    Map.Entry<String, String> entry= iterator.next();
    System.out.println(entry.getKey()+" :"+ entry.getValue());}

HashMap四种遍历方式性能比较

比较方式

分别对四种遍历方式进行10W次迭代,比较用时。

代码

package net.xsoftlab.baike;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Map.Entry;publicclassTestMap{publicstaticvoidmain(String[] args){// 初始化,10W次赋值
        Map<Integer, Integer> map=newHashMap<Integer, Integer>();for(int i=0; i<100000; i++)
            map.put(i, i);/** 增强for循环,keySet迭代 **/long start= System.currentTimeMillis();for(Integer key: map.keySet()){
            map.get(key);}long end= System.currentTimeMillis();
        System.out.println("增强for循环,keySet迭代 -> "+(end- start)+" ms");/** 增强for循环,entrySet迭代 */
        start= System.currentTimeMillis();for(Entry<Integer, Integer> entry: map.entrySet()){
            entry.getKey();
            entry.getValue();}
        end= System.currentTimeMillis();
        System.out.println("增强for循环,entrySet迭代 -> "+(end- start)+" ms");/** 迭代器,keySet迭代 **/
        start= System.currentTimeMillis();
        Iterator<Integer> iterator= map.keySet().iterator();
        Integer key;while(iterator.hasNext()){
            key= iterator.next();
            map.get(key);}
        end= System.currentTimeMillis();
        System.out.println("迭代器,keySet迭代 -> "+(end- start)+" ms");/** 迭代器,entrySet迭代 **/
        start= System.currentTimeMillis();
        Iterator<Map.Entry<Integer, Integer>> iterator1= map.entrySet().iterator();
        Map.Entry<Integer, Integer> entry;while(iterator1.hasNext()){
            entry= iterator1.next();
            entry.getKey();
            entry.getValue();}
        end= System.currentTimeMillis();
        System.out.println("迭代器,entrySet迭代 -> "+(end- start)+" ms");}}

运行三次,比较结果

第一次

增强for循环,keySet迭代->37 ms
增强for循环,entrySet迭代->19 ms
迭代器,keySet迭代->14 ms
迭代器,entrySet迭代->9 ms

第二次

增强for循环,keySet迭代->29 ms
增强for循环,entrySet迭代->22 ms
迭代器,keySet迭代->19 ms
迭代器,entrySet迭代->12 ms

第三次

增强for循环,keySet迭代->27 ms
增强for循环,entrySet迭代->19 ms
迭代器,keySet迭代->18 ms
迭代器,entrySet迭代->10 ms

平均值

增强for循环,keySet迭代->31 ms
增强for循环,entrySet迭代->20 ms
迭代器,keySet迭代->17 ms
迭代器,entrySet迭代->10.33 ms

总结

  1. 增强for循环使用方便,但性能较差,不适合处理超大量级的数据。
  2. 迭代器的遍历速度要比增强for循环快很多,是增强for循环的2倍左右。
  3. 使用entrySet遍历的速度要比keySet快很多,是keySet的1.5倍左右。

Map 排序

HashMap、Hashtable、LinkedHashMap排序

注:TreeMap也可以使用此方法进行排序,但是更推荐下面的方法。


  • 作者:jonssonyan
  • 原文链接:https://blog.csdn.net/y1534414425/article/details/110012007
    更新时间:2022年6月10日09:08:19 ,共 6791 字。