31.Map集合用法、遍历、排序与常见API

概要:

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

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

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

类型介绍

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

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

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

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

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

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

插入元素    map.put("key1""value1");

获取元素    map.get("key1")

移除元素  map.remove("key1");

清空map  map.clear();

测试代码
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<String, String> map = new HashMap<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 = new LinkedHashMap<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 = new String[size];map = new TreeMap<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 = new String[size];map = new Hashtable<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插入与读取性能比较

测试环境   jdk1.7.0_80

测试结果

Map 遍历

初始化数据

Map<String, String> map = new HashMap<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());

}

总结

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

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

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

Map 排序

HashMap、Hashtable、LinkedHashMap排序

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

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

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

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

常用API

clear()从 Map 中删除所有映射
remove(Object key)从 Map 中删除键和关联的值
put(Object key, Object value)将指定值与指定键相关联
putAll(Map t)将指定 Map 中的所有映射复制到此 map
entrySet()返回 Map 中所包含映射的 Set 视图。Set 中的每个元素都是一个 Map.Entry 对象,可以使用 getKey() 和 getValue() 方法(还有一个 setValue() 方法)访问后者的键元素和值元素
keySet()返回 Map 中所包含键的 Set 视图。删除 Set 中的元素还将删除 Map 中相应的映射(键和值)
values()返回 map 中所包含值的 Collection 视图。删除 Collection 中的元素还将删除 Map 中相应的映射(键和值)
get(Object key)返回与指定键关联的值
containsKey(Object key)如果 Map 包含指定键的映射,则返回 true
containsValue(Object value)如果此 Map 将一个或多个键映射到指定值,则返回 true
isEmpty()如果 Map 不包含键-值映射,则返回 true
size()返回 Map 中的键-值映射的数目

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/132386.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用VSCode来查看二进制文件

2023年11月6日&#xff0c;周一下午 目录 方法1&#xff1a;安装插件Binary Viewer然后用vscode打开一个二进制文件&#xff0c;并点击右上角的"HEX"方法2&#xff1a;安装插件Binary然后用vscode打开一个二进制文件&#xff0c;并点击右上角的"B" 方法1&…

C-DS二叉树_另一棵树的子树

Description 给你两棵二叉树tree1和tree2,检验tree1中是否包含和tree2具有相同结构和结点值的子树。如果存在,输出true;否则,输出false。 Input 第一行输入t,表示有t个测试样例。 第二行首先输入n1,接着输入n1个整数,表示二叉树tree1。 第三行首先输入n2,接着输入n…

Vite 的基本原理,和 webpack 在开发阶段的比较

目录 1&#xff0c;webpack 的流程2&#xff0c;Vite 的流程简单编译 3&#xff0c;总结 主要对比开发阶段。 1&#xff0c;webpack 的流程 开发阶段大致流程&#xff1a;指定一个入口文件&#xff0c;对相关的模块&#xff08;js css img 等&#xff09;先进行打包&#xff0…

【Unity基础】7.动画状态参数

【Unity基础】7.动画状态参数 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity基础系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;创建动画状态 (1) 创建动画状态 不好意思各位~最近工作比较忙&#xff0c;稍微耽误了这两周的博客。话…

Hydra post登录框爆破

文章目录 无token时的Hydra post登录框爆破带Token时的Hydra post登录框爆破 无token时的Hydra post登录框爆破 登录一个无验证码和token的页面&#xff0c;同时抓包拦截 取出发送数据包&#xff1a;usernameadb&password133&submitLogin 将用户名和密码替换 userna…

项目部署文档

申请SSL证书 先申请,用免费的 下载证书 先将下载下来的保存起来 服务器安装JDK: 创建develop目录 mkdir /usr/local/develop/ 把JDK压缩包上传到/usr/local/develop/目录 解压安装包 并且将安装到指定目录 tar -zxvf /usr/local/develop/jdk-8u191-linux-x64.tar.gz -C /us…

传感与表面分析

传感技术同计算机技术与通信一起被称为信息技术的三大支柱。从物联网角度看&#xff0c;传感技术是衡量一个国家信息化程度的重要标志&#xff0c;作为第二届杭州物联网暨传感技术应用高峰论坛&#xff0c;推进我国传感器产业化快速发展。传感技术是关于从自然信源获取信息&…

【tcl 脚本学习-- tcl 脚本常用命令介绍】

文章目录 TCL在Linux下如何执行TCL 常用语法TCL 中括号和大括号和小括号的详细介绍TCL Catch 命令介绍TCL 中 eval 详细介绍 TCL&#xff08;Tool Command Language&#xff09;是一种动态编程语言&#xff0c;通常用于嵌入到应用程序中以提供脚本功能&#xff0c;或者用于测试…

CMake重要指令常用变量

什么是CMake? 没有使用CMake和使用CMake构建的区别&#xff1f; CMake的基本语法 语法格式&#xff1a; 指令(参数1 参数2...)赋值操作 如 把hello.cpp 赋值给变量HELLO set(HELLO hello.cpp)取变量的值&#xff1a; ${HELLO}但在if控制语句中是直接使用变量名。 if(HEL…

lazarus:数据集快速导出为excel、csv、sql及其他多种格式

lazarus被成为快速开发工具&#xff0c;为什么说“快速”&#xff0c;重要的一点是&#xff0c;很多工具是现成的&#xff0c;可以拿来直接就用。比如数据导出&#xff0c;如果需要把数据集导出为excel格式文件&#xff0c;写代码可能需要很多时间。lazarus就不用了&#xff0c…

Java连接Redis并操作Redis中的常见数据类型

目录 一. Java连接Redis 1. 导入依赖 2. 建立连接 二. Java操作Redis的常见数据类型存储 1. Redis字符串(String) 2. Redis哈希(Hash) 3. Redis列表&#xff08;List&#xff09; 4. Redis集合&#xff08;Set&#xff09; 一. Java连接Redis 1. 导入依赖 pom依赖…

外汇天眼:全员免费,赢奖金!

外汇市场一直以来都是金融投资者的热门领域之一&#xff0c;但对于新手来说&#xff0c;了解和掌握外汇交易可能需要时间和经验。为了帮助新手入门&#xff0c;提高交易技能&#xff0c;外汇模拟交易应运而生。为的是能够零风险无压力地帮助外汇投资者更好地掌握外汇交易的技巧…

【GEE】4、 Google 地球引擎中的数据导入和导出

1简介 在本模块中&#xff0c;我们将讨论以下概念&#xff1a; 如何将您自己的数据集引入 GEE。如何将来自遥感数据的值与您自己的数据相关联。如何从 GEE 导出特征。 2背景 了解动物对环境的反应对于了解如何管理这些物种至关重要。虽然动物被迫做出选择以满足其基本需求&am…

JWT登录校验

工作原理 下面来详细看看 UTF-8 是如何工作的&#xff0c;以及为什么它会根据被编码的字符具有不同的长度。 一、JWT是什么&#xff1f; 在介绍JWT之前&#xff0c;我们先来回顾一下利用token进行用户身份验证的流程&#xff1a; 1、客户端使用用户名和密码请求登录 2、服务端…

Etcd 解析

Etcd 解析 Etcd 是 Kubernetes 集群中的一个十分重要的组件,用于保存集群所有的网络配置和对象的状态信息。在后面具体的安装环境中,我们安装的 etcd 的版本是 v3.1.5,整个 Kubernetes 系统中一共有两个服务需要用到 etcd 用来协同和存储配置,分别是: 网络插件 flannel、…

STM32中微秒延时的实现方式

STM32中微秒延时的实现方式 0.前言一、裸机实现方式二、FreeRTOS实现方式三、定时器实现&#xff08;通用&#xff09;4、总结 0.前言 最近在STM32驱动移植过程中需要用到微秒延时来实现一些外设的时序&#xff0c;由于网上找到的驱动方法良莠不齐&#xff0c;笔者在实现时序过…

ARCGIS---dem生成高程点

1添加DEM 2在ArcToolbox中点击“3D Analyst工具\转换\由栅格转出\栅格转多点”&#xff0c;调用栅格转多点工具。 3在显示的栅格转多点对话框内&#xff0c;输入栅格选择下载的dem数据&#xff0c;为了保证正常输出&#xff0c;输出要素类最好是默认&#xff0c;方法选择ZTOL…

【SQL篇】一、Flink动态表与流的关系以及DDL语法

文章目录 1、启动SQL客户端2、SQL客户端常用配置3、动态表和持续查询4、将流转为动态表5、用SQL持续查询6、动态表转为流7、时间属性8、DDL-数据库相关9、DDL-表相关 1、启动SQL客户端 启动Flink&#xff08;基于yarn-session模式为例&#xff09;&#xff1a; /opt/module/f…

Flink SQL 窗口聚合详解

1.滚动窗⼝&#xff08;TUMBLE&#xff09; **滚动窗⼝定义&#xff1a;**滚动窗⼝将每个元素指定给指定窗⼝⼤⼩的窗⼝&#xff0c;滚动窗⼝具有固定⼤⼩&#xff0c;且不重叠。 例如&#xff0c;指定⼀个⼤⼩为 5 分钟的滚动窗⼝&#xff0c;Flink 将每隔 5 分钟开启⼀个新…

2023年第二届长沙市职业技能大赛“网络安全“项目样题任务书

2023年第二届长沙市职业技能大赛网络安全项目样题任务书 模块A:企业基础设施安全A-1.任务一 登录安全加固(windows、linux)A-2.任务二 数据库加固(Linux)A-3.任务三 服务加固 SSH\VSFTPD(Linux)A-4.任务四 防火墙策略(Linux)模块B:网络安全事件响应、数字取证调查和应…