- 浏览: 978503 次
- 性别:
- 来自: 山西
文章分类
最新评论
-
白小默:
你好 可以提供下源码DEMO吗,不知为何,我导出来的excel ...
jxls 使用模板文件导出生成excel -
zkzqzzz:
博主威武!
让微信二维码扫描您的APK -
zkzqzzz:
感谢博主 原来那些类都不是必须的 或者自己写!!博主真棒 ...
抢红包插件实现原理浅析 -
zkzqzzz:
博主 请问你的其他类在哪里呢?
抢红包插件实现原理浅析 -
zkzqzzz:
其他类在哪呢?
抢红包插件实现原理浅析
首先,遍历map有以下方法:
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- public class MapTest {
- public static void main(String[] args) {
- Map<String, String> map = new HashMap<String, String>();
- map.put("1", "1");
- map.put("2", "2");
- map.put("3", "3");
- // 第一种:通过Map.keySet遍历key和value
- System.out.println("通过Map.keySet遍历key和value:");
- for (String key : map.keySet()) {
- System.out.println("key= " + key + " and value= " + map.get(key));
- }
- // 第二种:通过Map.entrySet使用iterator遍历key和value
- System.out.println("通过Map.entrySet使用iterator遍历key和value:");
- Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry<String, String> entry = it.next();
- System.out.println("key= " + entry.getKey() + " and value= "
- + entry.getValue());
- }
- // 第三种:通过Map.entrySet遍历key和value
- System.out.println("通过Map.entrySet遍历key和value:");
- for (Map.Entry<String, String> entry : map.entrySet()) {
- System.out.println("key= " + entry.getKey() + " and value= "
- + entry.getValue());
- }
- // 第四种:通过Map.values()遍历所有的value,但是不能遍历键key
- System.out.println("通过Map.values()遍历所有的value:");
- for (String v : map.values()) {
- System.out.println("value= " + v);
- }
- }
- }
import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class MapTest { public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("1", "1"); map.put("2", "2"); map.put("3", "3"); // 第一种:通过Map.keySet遍历key和value System.out.println("通过Map.keySet遍历key和value:"); for (String key : map.keySet()) { System.out.println("key= " + key + " and value= " + map.get(key)); } // 第二种:通过Map.entrySet使用iterator遍历key和value System.out.println("通过Map.entrySet使用iterator遍历key和value:"); Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } // 第三种:通过Map.entrySet遍历key和value System.out.println("通过Map.entrySet遍历key和value:"); for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } // 第四种:通过Map.values()遍历所有的value,但是不能遍历键key System.out.println("通过Map.values()遍历所有的value:"); for (String v : map.values()) { System.out.println("value= " + v); } } }
结果如下:
- 通过Map.keySet遍历key和value:
- key= 3 and value= 3
- key= 2 and value= 2
- key= 1 and value= 1
- 通过Map.entrySet使用iterator遍历key和value:
- key= 3 and value= 3
- key= 2 and value= 2
- key= 1 and value= 1
- 通过Map.entrySet遍历key和value:
- key= 3 and value= 3
- key= 2 and value= 2
- key= 1 and value= 1
- 通过Map.values()遍历所有的value:
- value= 3
- value= 2
- value= 1
通过Map.keySet遍历key和value: key= 3 and value= 3 key= 2 and value= 2 key= 1 and value= 1 通过Map.entrySet使用iterator遍历key和value: key= 3 and value= 3 key= 2 and value= 2 key= 1 and value= 1 通过Map.entrySet遍历key和value: key= 3 and value= 3 key= 2 and value= 2 key= 1 and value= 1 通过Map.values()遍历所有的value: value= 3 value= 2 value= 1
这四种方法都可以遍历map:
第一种是目前许多人最喜欢的一种方式,因为代码最少,看起来最简单,通过遍历keySet,再将key所对应的value查询出来,这里有一个二次取值的过程,所以并不推荐;
第二种和第三种原理是相同的,都是通过遍历Map.Entry的方式,将Entry中的key和value打印出来,第三种是比较推荐写法,因为采用jdk1.5后的遍历形式,代码看起来比较整洁;
第四种比较少用,因为我们大多数时候都是同时需要key和value的
综上所述,如果map里面内容比较少,其实采用哪种方式都可以,第一种和第三种相对简洁一些;但是一旦容量非常大时,更推荐采用第三种方式,相比于第一种将极大地节省性能。
修改一下代码,对执行时间执行一下测试
- import java.util.HashMap;
- import java.util.Map;
- public class MapTest {
- static long MAX_LONG = 1000000L;
- static int TIMES = 10;
- static Map<String, String> map1 = new HashMap<String, String>();
- static Map<String, String> map2 = new HashMap<String, String>();
- static {
- for (long i = 0; i < MAX_LONG; i++) {
- map1.put("1" + i, "abc" + i);
- map2.put("2" + i, "def" + i);
- }
- }
- public static void main(String[] args) {
- String valueStr = "";
- String keyStr = "";
- long start, end;
- double totalMs;
- totalMs = 0;
- for (int i = 0; i < TIMES; i++) {
- // 通过Map.keySet遍历key和value
- start = System.currentTimeMillis();
- for (String key : map1.keySet()) {
- keyStr = key;
- valueStr = map1.get(key);
- }
- end = System.currentTimeMillis();
- System.out.println("通过Map.keySet遍历key和value耗时 " + (end - start)
- + " ms ");
- totalMs += (end - start);
- }
- System.out.println("Times : " + TIMES + ", totalMs : " + totalMs
- + "ms, average :" + totalMs / TIMES + "ms");
- totalMs = 0;
- for (int i = 0; i < TIMES; i++) {
- // 通过Map.entrySet遍历key和value
- start = System.currentTimeMillis();
- for (Map.Entry<String, String> entry : map2.entrySet()) {
- keyStr = entry.getKey();
- valueStr = entry.getValue();
- }
- end = System.currentTimeMillis();
- System.out.println("通过Map.entrySet遍历key和value耗时 " + (end - start)
- + " ms ");
- totalMs += (end - start);
- }
- System.out.println("Times : " + TIMES + ", totalMs : " + totalMs
- + "ms, average :" + totalMs / TIMES + "ms");
- }
- }
import java.util.HashMap; import java.util.Map; public class MapTest { static long MAX_LONG = 1000000L; static int TIMES = 10; static Map<String, String> map1 = new HashMap<String, String>(); static Map<String, String> map2 = new HashMap<String, String>(); static { for (long i = 0; i < MAX_LONG; i++) { map1.put("1" + i, "abc" + i); map2.put("2" + i, "def" + i); } } public static void main(String[] args) { String valueStr = ""; String keyStr = ""; long start, end; double totalMs; totalMs = 0; for (int i = 0; i < TIMES; i++) { // 通过Map.keySet遍历key和value start = System.currentTimeMillis(); for (String key : map1.keySet()) { keyStr = key; valueStr = map1.get(key); } end = System.currentTimeMillis(); System.out.println("通过Map.keySet遍历key和value耗时 " + (end - start) + " ms "); totalMs += (end - start); } System.out.println("Times : " + TIMES + ", totalMs : " + totalMs + "ms, average :" + totalMs / TIMES + "ms"); totalMs = 0; for (int i = 0; i < TIMES; i++) { // 通过Map.entrySet遍历key和value start = System.currentTimeMillis(); for (Map.Entry<String, String> entry : map2.entrySet()) { keyStr = entry.getKey(); valueStr = entry.getValue(); } end = System.currentTimeMillis(); System.out.println("通过Map.entrySet遍历key和value耗时 " + (end - start) + " ms "); totalMs += (end - start); } System.out.println("Times : " + TIMES + ", totalMs : " + totalMs + "ms, average :" + totalMs / TIMES + "ms"); } }
以下是测试结果:
- 通过Map.keySet遍历key和value耗时 186 ms
- 通过Map.keySet遍历key和value耗时 189 ms
- 通过Map.keySet遍历key和value耗时 87 ms
- 通过Map.keySet遍历key和value耗时 89 ms
- 通过Map.keySet遍历key和value耗时 84 ms
- 通过Map.keySet遍历key和value耗时 92 ms
- 通过Map.keySet遍历key和value耗时 85 ms
- 通过Map.keySet遍历key和value耗时 94 ms
- 通过Map.keySet遍历key和value耗时 89 ms
- 通过Map.keySet遍历key和value耗时 91 ms
- Times : 10, totalMs : 1086.0ms, average :108.6ms
- 通过Map.entrySet遍历key和value耗时 112 ms
- 通过Map.entrySet遍历key和value耗时 98 ms
- 通过Map.entrySet遍历key和value耗时 71 ms
- 通过Map.entrySet遍历key和value耗时 65 ms
- 通过Map.entrySet遍历key和value耗时 65 ms
- 通过Map.entrySet遍历key和value耗时 64 ms
- 通过Map.entrySet遍历key和value耗时 64 ms
- 通过Map.entrySet遍历key和value耗时 65 ms
- 通过Map.entrySet遍历key和value耗时 65 ms
- 通过Map.entrySet遍历key和value耗时 65 ms
- Times : 10, totalMs : 734.0ms, average :73.4ms
通过Map.keySet遍历key和value耗时 186 ms 通过Map.keySet遍历key和value耗时 189 ms 通过Map.keySet遍历key和value耗时 87 ms 通过Map.keySet遍历key和value耗时 89 ms 通过Map.keySet遍历key和value耗时 84 ms 通过Map.keySet遍历key和value耗时 92 ms 通过Map.keySet遍历key和value耗时 85 ms 通过Map.keySet遍历key和value耗时 94 ms 通过Map.keySet遍历key和value耗时 89 ms 通过Map.keySet遍历key和value耗时 91 ms Times : 10, totalMs : 1086.0ms, average :108.6ms 通过Map.entrySet遍历key和value耗时 112 ms 通过Map.entrySet遍历key和value耗时 98 ms 通过Map.entrySet遍历key和value耗时 71 ms 通过Map.entrySet遍历key和value耗时 65 ms 通过Map.entrySet遍历key和value耗时 65 ms 通过Map.entrySet遍历key和value耗时 64 ms 通过Map.entrySet遍历key和value耗时 64 ms 通过Map.entrySet遍历key和value耗时 65 ms 通过Map.entrySet遍历key和value耗时 65 ms 通过Map.entrySet遍历key和value耗时 65 ms Times : 10, totalMs : 734.0ms, average :73.4ms
可以看出,百万级别的量时,使用keySet和entrySet遍历,执行时间大概为1.5:1,这并不是最主要的差异。真正的差异还是必须看代码
map.get(key))
时执行的hash操作
- /**
- * Returns the value to which the specified key is mapped,
- * or {@code null} if this map contains no mapping for the key.
- *
- * <p>More formally, if this map contains a mapping from a key
- * {@code k} to a value {@code v} such that {@code (key==null ? k==null :
- * key.equals(k))}, then this method returns {@code v}; otherwise
- * it returns {@code null}. (There can be at most one such mapping.)
- *
- * <p>A return value of {@code null} does not <i>necessarily</i>
- * indicate that the map contains no mapping for the key; it's also
- * possible that the map explicitly maps the key to {@code null}.
- * The {@link #containsKey containsKey} operation may be used to
- * distinguish these two cases.
- *
- * @see #put(Object, Object)
- */
- public V get(Object key) {
- if (key == null)
- return getForNullKey();
- int hash = hash(key.hashCode());
- for (Entry<K,V> e = table[indexFor(hash, table.length)];
- e != null;
- e = e.next) {
- Object k;
- if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
- return e.value;
- }
- return null;
- }
/** * Returns the value to which the specified key is mapped, * or {@code null} if this map contains no mapping for the key. * * <p>More formally, if this map contains a mapping from a key * {@code k} to a value {@code v} such that {@code (key==null ? k==null : * key.equals(k))}, then this method returns {@code v}; otherwise * it returns {@code null}. (There can be at most one such mapping.) * * <p>A return value of {@code null} does not <i>necessarily</i> * indicate that the map contains no mapping for the key; it's also * possible that the map explicitly maps the key to {@code null}. * The {@link #containsKey containsKey} operation may be used to * distinguish these two cases. * * @see #put(Object, Object) */ public V get(Object key) { if (key == null) return getForNullKey(); int hash = hash(key.hashCode()); for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) return e.value; } return null; }
计算hashCode是CPU密集运算,非常耗费CPU资源,如果对一个比较大的map进行遍历,会出现CPU迅速飚高的现象,直接影响机器的响应速度,在多线程的情况下,简直就是一场灾难,而采用entrySet来进行遍历,则无此问题,对这个有兴趣的同学,可以使用自己的机器试一试。
发表评论
-
java通过sftp JSch 上传文件下载文件查看文件目录,测试可用
2019-12-19 18:19 987基于maven ... -
服务器之间的 zip 文件定时传送
2019-12-19 10:28 5261、expect 安装 将expect和tcl的软 ... -
Java/web/jsp根据pdf模板生成荣誉证书PDF文件
2019-07-19 14:48 9811.前言 最近博主在 ... -
Java生成荣誉证书PDF文件
2019-07-19 13:08 1407Java生成荣誉证书PD ... -
百度云API刷脸
2019-07-13 11:41 639刷脸登录是基于人工智能、生物识别、3D传感、大数据风控技术, ... -
maven--maven配置多个源文件夹
2019-06-13 21:32 937需求 Maven 为我们提供了一致的项目目录配置(源文件 ... -
绿盟检测出“检测到目标URL存在http host头攻击漏洞”如何解决
2019-06-09 10:00 1019绿盟检测出“检测到目标URL存在http host头攻击漏 ... -
Linux安装apache及其简单的反向代理配置
2019-06-07 09:06 647Apache简介 Apache HTTP Se ... -
Linux二进制安装apache2.4.25
2019-06-07 09:06 720Linux二进制安装apache2.4. ... -
weblogic配置https,http自动跳转转https,ssl
2019-05-21 09:44 960最近,公司要求将http ... -
bootstrap-table组合表头
2019-03-06 10:04 921bootstrap-table组合表头 ... -
[Weblogic]如何清理缓存
2019-03-04 15:23 861[Weblogic]如何清理缓存 ... -
Guns第十节Swagger的讲解
2019-01-23 16:51 6532018年08月01日 15:54:30 ze ... -
Anaconda详细安装使用教程
2019-01-22 15:07 626关注微信公众号【Mi ... -
Windows系统下Eclipse上搭建Python开发环境
2019-01-22 15:00 332Windows系统下Eclipse上搭 ... -
Python 3.6 中使用pdfminer解析pdf文件
2019-01-22 14:50 937所使用python环境为最新 ... -
Python提取PDF内容(文本、图像、线条等)
2019-01-22 14:43 7551使用Python抽取PDF文件内 ... -
用python解析pdf中的文本与表格【pdfplumber的安装与使用】
2019-01-22 14:40 1540我们接触到的很多文档资料都是以pdf格式存在的,比如:论文, ... -
java实现PDF转HTML
2019-01-21 10:14 935java实现PDF转HTML 问题场景: ... -
JAVA PDFBOX 读取PDF表格
2019-01-18 17:39 2997最近在帮公司做工具,需要读取PDF中表格的数据。网上查了, ...
相关推荐
在Java编程中,遍历大容量的Map是一个常见的操作,特别是在处理大数据或内存优化的场景下,选择正确的遍历方式至关重要。以下是对标题和描述中提及的四种遍历Map方法的详细说明: 1. **通过Map.keySet遍历key和...
- 迭代器:定义前向迭代器,实现`begin()`和`end()`方法,允许遍历`Map`。 自定义`Map`的一个挑战是实现高效的查找、插入和删除操作,这通常需要熟练掌握二叉搜索树的特性,尤其是红黑树的插入和旋转规则。此外,...
在Java编程语言中,Map接口是集合框架的重要组成部分,它提供了键值对(Key-Value)的数据存储方式。Map不是列表或数组,它允许通过键来查找...选择合适的Map实现,以及正确地遍历和操作Map,都是提高程序性能的关键。
Java中的Map集合是一种存储键值对的数据结构,它允许通过键来访问对应的值。Map接口在Java的`java.util`包中定义,...通过选择合适的Map类型,调整大小,以及正确地遍历和操作Map,可以提高程序性能并避免潜在的问题。
本篇文章将深入探讨如何正确地使用`std::map`,以及它提供的各种函数。 一、map的基本结构与类型定义 `std::map`由键值对组成,每个元素都有一个唯一的键和一个相关联的值。它的基本定义如下: ```cpp template, ...
例如,可以定义一个包含整型和字符串的结构体`StudentInfo`,并重载`运算符,以便`map`可以正确排序这些元素。 8. **迭代器操作**: - `lower_bound(key)`返回第一个大于等于key的元素的迭代器。 - `upper_bound...
7. **大小和容量**:`map::size()`返回元素数量,`map::empty()`检查Map是否为空,`map::max_size()`返回Map能容纳的最大元素数。 8. **迭代器**:Map提供了双向迭代器,支持前向和后向遍历。`iterator`用于读写,`...
5. **并发与线程安全**:在多线程环境下,不线程安全的Map如HashMap在并发操作下可能导致数据不一致,而线程安全的Map如Java的ConcurrentHashMap则能保证在并发环境下的正确性。 6. **性能优化**:选择合适的Map...
- **容器分类**:Java集合框架主要分为两大类:集合(Collection)和映射(Map)。集合类用于存储单一类型的元素,而Map则用于存储键值对。 2. **Collection接口** - **常用方法**:Collection接口提供了add、...
在测试过程中,理解如何创建、遍历和修改Map对象是非常重要的,因为这会直接影响到代码的性能和正确性。 当我们谈论“test-map”,我们可能在讨论以下几种情况: 1. 单元测试:这是针对代码中的最小可测试单元进行...
初始容量是指哈希表在创建时预分配的空间大小,而负载因子则是衡量哈希表负载程度的一个参数,表示哈希表在达到多大比例的占用率时需要进行扩容。 2. **加入**:HashMap类提供`加入`方法,用于将键值对插入到哈希表...
4. **键值对**:键(Key)必须实现`hashCode()`和`equals()`方法,以确保正确的哈希计算和比较。值(Value)可以是任意对象。 5. **键的唯一性**:在`HashMap`中,键是唯一的,相同的键不能添加多次。如果尝试插入...
如果桶内形成链表,通过遍历链表并使用键对象的equals()方法来找到正确的键值对。 3. **获取值对象**:在获取值时,HashMap首先根据键的hashCode找到bucket,然后通过键的equals()方法与链表中的键进行比较,找到...
在这个项目中,开发者可能在创建或优化一个使用Map的功能,可能是为了提高性能、处理复杂的数据结构或者确保正确性。 描述提到“地图测试”,这可能指的是针对Map对象的单元测试或集成测试,以验证其在实际应用中的...
了解Map时,需理解键的唯一性、键值对的概念以及遍历Map的方法。 4. **容器的体系** 集合框架的设计是基于继承和接口的。例如,List、Set和Map都继承自AbstractCollection,提供了基本的集合操作。List接口继承自...
这个数据结构允许我们以接近常数时间的复杂度进行插入、查找和删除操作,极大地提高了程序的执行效率。下面我们将深入探讨`std::unordered_map`的使用、特性以及一些实例。 1. **引入头文件** 在C++中使用`std::...
在自定义类中,必须重写这两个方法以确保键的正确索引和查找。 10. **HashMap与Hashtable的区别**:HashMap允许null键和值,而Hashtable不允许。Hashtable是线程安全的,适合多线程环境,而HashMap则不是。HashMap...
因此,这两个方法在HashMap中的正确实现对于保证其精确性和正确性至关重要。 6. **使用Object作为HashMap的key**:当Object对象作为HashMap的key时,必须保证Object的hashCode()方法返回的哈希码不会改变,因为如果...
拉链法将链表和数组结合,确保了即使有哈希冲突,也能通过遍历链表找到正确的元素。 2. **JDK1.8之后**:在JDK1.8中,当链表长度超过8且数组长度超过64时,HashMap会将链表转换为红黑树。红黑树是一种自平衡二叉...