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

概要:

java.util 中的集合类包含 Java 中某些最常用的类。最常用的集合类是 List 和 Map。

Map 提供了一个更通用的元素存储方法。Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。

本文主要介绍java map的初始化、用法、map的四种常用的遍历方式、map的排序以及常用api。

1、Map用法

类型介绍

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

  1. 通用Map,用于在应用程序中管理映射,通常在 java.util 程序包中实现

HashMap、Hashtable、Properties、LinkedHashMap、IdentityHashMap、TreeMap、WeakHashMap、ConcurrentHashMap

  1. 专用Map,通常我们不必亲自创建此类Map,而是通过某些其他类对其进行访问

java.util.jar.Attributes、javax.print.attribute.standard.PrinterStateReasons、java.security.Provider、java.awt.RenderingHints、javax.swing.UIDefaults

  1. 一个用于帮助我们实现自己的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 map = new HashMap();

插入元素

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

获取元素

map.get("key1")

移除元素

map.remove("key1");

清空map

map.clear();

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

public class Test {
 static int hashMapW = 0;
 static int hashMapR = 0;
 static int linkMapW = 0;
 static int linkMapR = 0;
 static int treeMapW = 0;
 static int treeMapR = 0;
 static int hashTableW = 0;
 static int hashTableR = 0;
 
 public static void main(String[] args) {
 for (int i = 0; i < 10; i++) {
 Test test = new Test();
 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);
 }
 
 public void test(int size) {
 int index;
 Random random = new Random();
 String[] key = new String[size];
 
 // HashMap 插入
 Map map = new HashMap();
 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 = new LinkedHashMap();
 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 = new String[size];
 map = new TreeMap();
 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 = new String[size];
 map = new Hashtable();
 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");
 }
}

3、Map 遍历

初始化数据

Map map = new HashMap();
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 entry : map.entrySet()) {
 System.out.println(entry.getKey() + " :" + entry.getValue());
}

迭代器遍历

使用keySet()遍历

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

使用entrySet()遍历

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

HashMap四种便利方式性能比较
比较方式

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

public class TestMap {
 
 public static void main(String[] args) {
 // 初始化,10W次赋值
 Map map = new HashMap();
 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 entry : map.entrySet()) {
 entry.getKey();
 entry.getValue();
 }
 end = System.currentTimeMillis();
 System.out.println("增强for循环,entrySet迭代 -> " + (end - start) + " ms");
 
 /** 迭代器,keySet迭代 */
 start = System.currentTimeMillis();
 Iterator 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 iterator1 = map.entrySet().iterator();
 Map.Entry 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

总结

增强for循环使用方便,但性能较差,不适合处理超大量级的数据。

迭代器的遍历速度要比增强for循环快很多,是增强for循环的2倍左右。

使用entrySet遍历的速度要比keySet快很多,是keySet的1.5倍左右。

4、Map 排序

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

Map map = new HashMap();
map.put("a", "c");
map.put("b", "b");
map.put("c", "a");
 
// 通过ArrayList构造函数把map.entrySet()转换成list
List list = new ArrayList(map.entrySet());
// 通过比较器实现比较排序
Collections.sort(list, new Comparator() {
 public int compare(Map.Entry mapping1, Map.Entry mapping2) {
 return mapping1.getKey().compareTo(mapping2.getKey());
 }
});
 
for (Map.Entry mapping : list) {
 System.out.println(mapping.getKey() + " :" + mapping.getValue());
}

TreeMap排序
TreeMap默认按key进行升序排序,如果想改变默认的顺序,可以使用比较器:

Map map = new TreeMap(new Comparator() {
 public int compare(String obj1, String obj2) {
 return obj2.compareTo(obj1);// 降序排序
 }
});
map.put("a", "c");
map.put("b", "b");
map.put("c", "a");
 
for (String key : map.keySet()) {
 System.out.println(key + " :" + map.get(key));
}

按value排序(通用)

Map map = new TreeMap();
 map.put("a", "c");
 map.put("b", "b");
 map.put("c", "a");
 
 // 通过ArrayList构造函数把map.entrySet()转换成list
 List list = new ArrayList(map.entrySet());
 // 通过比较器实现比较排序
 Collections.sort(list, new Comparator() {
 public int compare(Map.Entry mapping1, Map.Entry mapping2) {
 return mapping1.getValue().compareTo(mapping2.getValue());
 }
 });
 
 for (String key : map.keySet()) {
 System.out.println(key + " :" + map.get(key));
 }

5、常用API

作者:princeAladdin原文地址:https://blog.csdn.net/weixin_45817985/article/details/134397181

%s 个评论

要回复文章请先登录注册