`
darkranger
  • 浏览: 25602 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JAVA的遍历MAP

map 
阅读更多
Java Map遍历方式的选择
1. 阐述
  对于Java中Map的遍历方式,很多文章都推荐使用entrySet,认为其比keySet的效率高很多。理由是:entrySet方法一次拿到所有key和value的集合;而keySet拿到的只是key的集合,针对每个key,都要去Map中额外查找一次value,从而降低了总体效率。那么实际情况如何呢?
  为了解遍历性能的真实差距,包括在遍历key+value、遍历key、遍历value等不同场景下的差异,我试着进行了一些对比测试。
2. 对比测试
  一开始只进行了简单的测试,但结果却表明keySet的性能更好,这一点让我很是费解,不都说entrySet明显好于keySet吗?为了进一步地进行验证,于是采用了不同的测试数据进行更详细的对比测试。
2.1 测试数据
2.1.1 HashMap测试数据
HashMap-1,大小为100万,key和value均为String,key的值为1、2、3……1000000:
Map<String, String> map = new HashMap<String, String>();
String key, value;
for (i = 1; i <= num; i++) {
    key = "" + i;
    value = "value";
    map.put(key, value);
}

HashMap-2,大小为100万,key和value均为String,key的值为50、100、150、200、……、50000000:

Map<String, String> map = new HashMap<String, String>();
String key, value;
for (i = 1; i <= num; i++) {
    key = "" + (i * 50);
    value = "value";
    map.put(key, value);
}


2.1.2 TreeMap测试数据
TreeMap-1,大小为100万,key和value均为String,key的值为1、2、3……1000000:
Map<String, String> map = new TreeMap<String, String>();
String key, value;
for (i = 1; i <= num; i++) {
    key = "" + i;
    value = "value";
    map.put(key, value);
}


TreeMap-2,大小为100万,key和value均为String,key的值为50、100、150、200、……、50000000,更离散:
Map<String, String> map = new TreeMap<String, String>();
String key, value;
for (i = 1; i <= num; i++) {
    key = "" + (i * 50);
    value = "value";
    map.put(key, value);
}

2.2 测试场景
  分别使用keySet、entrySet和values的多种写法测试三种场景:遍历key+value、遍历key、遍历value的场景。
2.2.1 遍历key+value
keySet遍历key+value(写法1):
Iterator<String> iter = map.keySet().iterator();
while (iter.hasNext()) {
    key = iter.next();
    value = map.get(key);
}

keySet遍历key+value(写法2):
for (String key : map.keySet()) {
    value = map.get(key);
}

entrySet遍历key+value(写法1):
Iterator<Entry<String, String>> iter = map.entrySet().iterator();
Entry<String, String> entry;
while (iter.hasNext()) {
    entry = iter.next();
    key = entry.getKey();
    value = entry.getValue();
}

 entrySet遍历key+value(写法2):
for (Entry<String, String> entry: map.entrySet()) {
    key = entry.getKey();
    value = entry.getValue();
}

2.2.2 遍历key
keySet遍历key(写法1):
Iterator<String> iter = map.keySet().iterator();
while (iter.hasNext()) {
    key = iter.next();
}

keySet遍历key(写法2):
for (String key : map.keySet()) {
}
 entrySet遍历key(写法1):
Iterator<Entry<String, String>> iter = map.entrySet().iterator();
while (iter.hasNext()) {
    key = iter.next().getKey();
}
entrySet遍历key(写法2):
for (Entry<String, String> entry: map.entrySet()) {
    key = entry.getKey();
}
2.2.3 遍历value
keySet遍历value(写法1):
Iterator<String> iter = map.keySet().iterator();
while (iter.hasNext()) {
    value = map.get(iter.next());
}
keySet遍历value(写法2):
for (String key : map.keySet()) {
    value = map.get(key);
}
entrySet遍历value(写法1):
Iterator<Entry<String, String>> iter = map.entrySet().iterator();
while (iter.hasNext()) {
value = iter.next().getValue();
}
entrySet遍历value(写法2):
for (Entry<String, String> entry: map.entrySet()) {
    value = entry.getValue();
}
values遍历value(写法1):
Iterator<String> iter = map.values().iterator();
while (iter.hasNext()) {
value = iter.next();
}
values遍历value(写法2):
for (String value : map.values()) {
}
2.3 测试结果
2.3.1 HashMap测试结果
单位:毫秒
HashMap-1
HashMap-2
keySet遍历key+value(写法1)
39
93
keySet遍历key+value(写法2)
38
87
entrySet遍历key+value(写法1)
43
86
entrySet遍历key+value(写法2)
43
85
 
单位:毫秒
HashMap-1
HashMap-2
keySet遍历key(写法1)
27
65
keySet遍历key(写法2)
26
64
entrySet遍历key(写法1)
35
75
entrySet遍历key(写法2)
34
74
 
单位:毫秒
HashMap-1
HashMap-2
keySet遍历value(写法1)
38
87
keySet遍历value(写法2)
37
87
entrySet遍历value(写法1)
34
61
entrySet遍历value(写法2)
32
62
values遍历value(写法1)
26
48
values遍历value(写法2)
26
48
2.3.2 TreeMap测试结果
单位:毫秒
TreeMap-1
TreeMap-2
keySet遍历key+value(写法1)
430
451
keySet遍历key+value(写法2)
429
450
entrySet遍历key+value(写法1)
77
84
entrySet遍历key+value(写法2)
70
68
 
单位:毫秒
TreeMap-1
TreeMap-2
keySet遍历key(写法1)
50
49
keySet遍历key(写法2)
49
48
entrySet遍历key(写法1)
66
64
entrySet遍历key(写法2)
65
63
 
单位:毫秒
TreeMap-1
TreeMap-2
keySet遍历value(写法1)
432
448
keySet遍历value(写法2)
430
448
entrySet遍历value(写法1)
62
61
entrySet遍历value(写法2)
62
61
values遍历value(写法1)
46
46
values遍历value(写法2)
45
46
3. 结论
3.1 如果你使用HashMap
同时遍历key和value时,keySet与entrySet方法的性能差异取决于key的具体情况,如复杂度(复杂对象)、离散度、冲突率等。换言之,取决于HashMap查找value的开销。entrySet一次性取出所有key和value的操作是有性能开销的,当这个损失小于HashMap查找value的开销时,entrySet的性能优势就会体现出来。例如上述对比测试中,当key是最简单的数值字符串时,keySet可能反而会更高效,耗时比entrySet少10%。总体来说还是推荐使用entrySet。因为当key很简单时,其性能或许会略低于keySet,但却是可控的;而随着key的复杂化,entrySet的优势将会明显体现出来。当然,我们可以根据实际情况进行选择
只遍历key时,keySet方法更为合适,因为entrySet将无用的value也给取出来了,浪费了性能和空间。在上述测试结果中,keySet比entrySet方法耗时少23%。
只遍历value时,使用vlaues方法是最佳选择,entrySet会略好于keySet方法。
在不同的遍历写法中,推荐使用如下写法,其效率略高一些:
for (String key : map.keySet()) {
    value = map.get(key);
}
 
for (Entry<String, String> entry: map.entrySet()) {
    key = entry.getKey();
    value = entry.getValue();
}
 
for (String value : map.values()) {
}

3.2 如果你使用TreeMap
同时遍历key和value时,与HashMap不同,entrySet的性能远远高于keySet。这是由TreeMap的查询效率决定的,也就是说,TreeMap查找value的开销较大,明显高于entrySet一次性取出所有key和value的开销。因此,遍历TreeMap时强烈推荐使用entrySet方法。
只遍历key时,keySet方法更为合适,因为entrySet将无用的value也给取出来了,浪费了性能和空间。在上述测试结果中,keySet比entrySet方法耗时少24%。
只遍历value时,使用vlaues方法是最佳选择,entrySet也明显优于keySet方法。
在不同的遍历写法中,推荐使用如下写法,其效率略高一些:
for (String key : map.keySet()) {
    value = map.get(key);
}
 
for (Entry<String, String> entry: map.entrySet()) {
    key = entry.getKey();
    value = entry.getValue();
}
 
for (String value : map.values()) {
}

分享到:
评论

相关推荐

    java遍历Map对象的说有数据

    ### Java遍历Map对象的所有数据 在Java编程中,`Map`接口是Java集合框架中的一个关键组成部分,它用于存储键值对。本篇文章将详细解释如何遍历`Map`对象的所有数据,并介绍几种常见的遍历方法。我们将重点讨论通过`...

    JAVA遍历Map所有元素.doc

    JAVA遍历Map所有元素 JAVA语言中,Map是一种非常常用的数据结构,用于存储键值对。然而,在遍历Map中的所有元素时,我们需要使用合适的方法来提高效率。本文将对JAVA中遍历Map所有元素的两种常用方法进行详细介绍。...

    java-遍历map

    ### 二、使用keySet遍历Map `Map`提供了一个`keySet()`方法,该方法返回`Map`中所有键的集合视图。通过这个方法,我们可以获取到一个包含所有键的`Set`集合,然后使用迭代器(`Iterator`)或增强型for循环(foreach...

    java遍历Map的几种方法分析

    在Java编程中,Map接口是用于存储键值对的数据结构,它提供了多种遍历Map的方法。本篇文章将详细分析Java中遍历Map的四种常见方法,帮助开发者更好地理解和运用这些技巧。 1. **for-each循环遍历** Java 5引入了...

    遍历MAP的几种方法

    遍历MAP的几种方法,利用keyset进行遍历,它的优点在于可以根据你所想要的key值得到你想要的 values,更具灵活性

    java 遍历Map及Map转化为二维数组的实例

    "java 遍历Map及Map转化为二维数组的实例" 在 Java 编程语言中,遍历 Map 及将其转化为二维数组是一种常见的操作。本文将详细介绍如何使用 Java 遍历 Map 及将其转化为二维数组,并提供实例代码以供参考。 1. 使用...

    java 遍历MAP的几种方法示例代码

    以下是Java中遍历Map的几种常见方法,包括使用增强的for循环、迭代器以及通过keySet()和entrySet()方法: 1. **增强的for循环(foreach)** 增强的for循环是Java 5引入的新特性,它可以简洁地遍历集合。对于Map,...

    java集合map取key使用示例 java遍历map

    本篇文章将详细讲解如何在Java中遍历Map并获取其键(key)。 1. **Map接口概述** Map接口在Java集合框架中定义了存储键值对的方法。每个键都是唯一的,通过键可以访问对应的值。Map接口没有实现List或Set接口,...

    Java Map 遍历实例与效率比较

    主要提供java中的map的遍历实例及效率比较

    另一种遍历Map的方式

    Map是一种常用的数据结构,在Java中有多种遍历Map的方式。今天,我们来讨论一种遍历Map的方式,即使用Map.Entry和Map.entrySet()。 Map.Entry是什么? ---------------- Map.Entry是一个接口,表示一个映射项,...

    java遍历JSON树

    ### Java遍历JSON树知识点详解 #### 一、前言 在处理Web应用程序中的数据时,JSON(JavaScript Object Notation)是一种非常常见的数据格式。它轻量级且易于读写,因此广泛应用于前后端的数据交互中。对于Java...

    JAVA遍历map的几种实现方法代码

    以下将详细介绍标题和描述中提到的几种遍历Map的Java实现方法,并讨论它们的效率问题。 1. **keySet遍历** 使用`keySet()`方法获取Map的所有键,然后通过迭代器或者增强for循环遍历键。这种方法只遍历键,如果需要...

    Java遍历Map键、值和获取Map大小的方法示例

    总结一下,Java中遍历Map主要有两种方法:通过`keySet()`遍历键并获取值,或通过`entrySet()`直接遍历键值对。获取Map大小则简单地调用`size()`方法即可。这些基本操作对于理解和使用Map数据结构至关重要,无论是在...

    Java遍历Map对象的四种方式

    如果只需要遍历Map的键或值,可以选择这种方式。通过`map.keySet()`获取键集合,或者`map.values()`获取值集合,再进行for-each循环。在性能上,这种方式略优于`entrySet()`,代码也更为简洁。 ```java // 遍历键 ...

    java Map 遍历方法

    #### 一、使用Iterator遍历Map 1. **通过`entrySet()`获取迭代器** 使用`Map.entrySet()`方法可以返回`Map`中所有映射关系的`Set`视图,然后可以通过迭代这个`Set`来遍历整个`Map`。 ```java Map, String&gt; ...

    java中Map集合的常用遍历方法及HashMap的应用实例

    1、遍历Map.entrySet():它的每一个元素都是Map.Entry对象,这个对象中, 放着的就是Map中的某一对key-value; 2、遍历Map.keySet():它是Map中key值的集合,我们可以通过遍历这个集合来 读取Map中的元素; 3、...

    map遍历的四种方法

    ### Map遍历的四种方法 在Java编程语言中,`Map`是一种常用的数据结构,用于存储键值对。为了能够有效地处理和操作这些键值对数据,熟练掌握遍历`Map`的方法至关重要。本文将详细介绍四种不同的遍历`Map`的方式,并...

    怎样遍历一个HashMap?

    可以通过2种方法遍历HashMap &lt;br&gt;Map map = new HashMap(); &lt;br&gt;for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) { &lt;br&gt; Map.Entry entry = (Map.Entry) iter.next(); &lt;br&gt; Object ...

    java集合MAP三种遍历

    本文将详细介绍Java中Map集合的三种遍历方法及其应用场景、优缺点等,帮助读者更好地理解和掌握Map的使用技巧。 ### 一、Map简介 `Map`接口是Java集合框架的一部分,它提供了基于键值对的数据存储方式。常见的实现...

Global site tag (gtag.js) - Google Analytics