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…

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…

STM32中微秒延时的实现方式

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

【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 分钟开启⼀个新…

从零开始制作一个割草机器人

项目背景 为啥要做一个割草机器人呢&#xff1f;&#xff08;个人因素&#xff1a;我梦想就是做一款人形机器人保护人类&#xff0c;解放人类&#xff09; 基础准备&#xff1a;我们公司本身做过高精度&#xff0c;基于高精度的技术扩展到农机自动化驾驶。目前可以实现AB线拖…

数字人IP为何成家电品牌年轻化营销黑马?

伴随着数字人概念的出现&#xff0c;家电品牌逐渐通过3D虚拟数字人定制&#xff0c;让数字人成为内容、变现一体的IP&#xff0c;形成一定影响力的品牌效应&#xff0c;利用长线内容沉淀粉丝&#xff0c;使品牌实现年轻化营销。 *图片源于网络 如近日在海尔智家旗下品牌发布会上…

uniapp踩坑之项目:uniapp数字键盘组件—APP端

//在components文件夹创建digitKeyboard文件夹&#xff0c;再创建digitKeyboard.vue <!-- 数字键盘 --> <template><view class"digit-keyboard"><view class"digit-keyboard_bg" tap"hide"></view><view clas…

平面扫描(Plane-sweeping)深度体会

先看文章 三维重建之平面扫描算法&#xff08;Plane-sweeping&#xff09;_plane sweeping_小玄玄的博客-CSDN博客 Plane Sweeping | 平面扫描 - 知乎 (zhihu.com) 注意平面Dm,这是其中一个平面&#xff0c;平面上有一个M点&#xff0c;这个点也再物体上。所以会被摄像机看到…

SSD-1B:Segmind的加速稳定扩散模型

Segmind 稳定扩散模型 (SSD-1B) 是稳定扩散 XL (SDXL) 缩小 50% 的精简版本&#xff0c;可提供 60% 的加速&#xff0c;同时保持高质量的文本到图像生成功能。 它已经过各种数据集的训练&#xff0c;包括 Grit 和 Midjourney scrap 数据&#xff0c;以增强其根据文本提示创建各…

docker---dockerfile相关知识

第 3 章 Docker 高级实践 在这一部分我们主要来介绍一些Docker的高级内容&#xff1a; Dockerfile 和 Docker compose 3.1 Dockerfile Dockerfile我们从下面的几个方面来介绍&#xff1a; Dockerfile简介 Dockerfile快速入门 Dockerfile详解 Dockerfile简单 实践 3.1.1 Docke…