原文:在 Java 中遍历 HashMap 的5种最佳方式_罗汉翔的博客-CSDN博客_java 遍历hashmap
将通过示例讨论在 Java 上遍历 HashMap[3] 的五种最佳方法。
- 使用 Iterator 遍历 HashMap EntrySet
- 使用 Iterator 遍历 HashMap KeySet
- 使用 For-each 循环迭代 HashMap
- 使用 Lambda 表达式[4]遍历 HashMap
- 使用 Stream API[5] 遍历 HashMap
通过
https://www.javaguides.net/2018/07/java-8-lambda-expressions.html [6]了解有关 lambda 表达式的信息
1. 使用 Iterator 遍历 HashMap EntrySet
-
package com.java.tutorials.iterations;
-
import java.util.HashMap;
-
import java.util.Iterator;
-
import java.util.Map;
-
import java.util.Map.Entry;
-
/**
-
* 在 Java 中遍历 HashMap 的5种最佳方法
-
* @author Ramesh Fadatare
-
*
-
*/
-
public class IterateHashMapExample {
-
public static void main(String[] args) {
-
// 1. 使用 Iterator 遍历 HashMap EntrySet
-
Map < Integer, String > coursesMap = new HashMap < Integer, String > ();
-
coursesMap.put(1, "C");
-
coursesMap.put(2, "C++");
-
coursesMap.put(3, "Java");
-
coursesMap.put(4, "Spring Framework");
-
coursesMap.put(5, "Hibernate ORM framework");
-
Iterator < Entry < Integer, String >> iterator = coursesMap.entrySet().iterator();
-
while (iterator.hasNext()) {
-
Entry < Integer, String > entry = iterator.next();
-
System.out.println(entry.getKey());
-
System.out.println(entry.getValue());
-
}
-
}
-
}
Output:
-
1
-
C
-
2
-
C++
-
3
-
Java
-
4
-
Spring Framework
-
5
-
Hibernate ORM framework
2. 使用 Iterator 遍历 HashMap KeySet
-
package com.java.tutorials.iterations;
-
import java.util.HashMap;
-
import java.util.Iterator;
-
import java.util.Map;
-
/**
-
* 在 Java 中遍历 HashMap 的5种最佳方法
-
* @author Ramesh Fadatare
-
*
-
*/
-
public class IterateHashMapExample {
-
public static void main(String[] args) {
-
Map < Integer, String > coursesMap = new HashMap < Integer, String > ();
-
coursesMap.put(1, "C");
-
coursesMap.put(2, "C++");
-
coursesMap.put(3, "Java");
-
coursesMap.put(4, "Spring Framework");
-
coursesMap.put(5, "Hibernate ORM framework");
-
// 2. 使用 Iterator 遍历 HashMap KeySet
-
Iterator < Integer > iterator = coursesMap.keySet().iterator();
-
while (iterator.hasNext()) {
-
Integer key = iterator.next();
-
System.out.println(key);
-
System.out.println(coursesMap.get(key));
-
}
-
}
-
}
Output:
-
1
-
C
-
2
-
C++
-
3
-
Java
-
4
-
Spring Framework
-
5
-
Hibernate ORM framework
3. 使用 For-each 循环遍历 HashMap
-
package com.java.tutorials.iterations;
-
import java.util.HashMap;
-
import java.util.Map;
-
/**
-
* 在 Java 中遍历 HashMap 的5种最佳方法
-
* @author Ramesh Fadatare
-
*
-
*/
-
public class IterateHashMapExample {
-
public static void main(String[] args) {
-
Map < Integer, String > coursesMap = new HashMap < Integer, String > ();
-
coursesMap.put(1, "C");
-
coursesMap.put(2, "C++");
-
coursesMap.put(3, "Java");
-
coursesMap.put(4, "Spring Framework");
-
coursesMap.put(5, "Hibernate ORM framework");
-
// 3. 使用 For-each 循环遍历 HashMap
-
for (Map.Entry < Integer, String > entry: coursesMap.entrySet()) {
-
System.out.println(entry.getKey());
-
System.out.println(entry.getValue());
-
}
-
}
-
}
Output:
-
1
-
C
-
2
-
C++
-
3
-
Java
-
4
-
Spring Framework
-
5
-
Hibernate ORM framework
4. 使用 Lambda 表达式遍历 HashMap
-
package com.java.tutorials.iterations;
-
import java.util.HashMap;
-
import java.util.Map;
-
/**
-
* 在 Java 中遍历 HashMap 的5种最佳方法
-
* @author Ramesh Fadatare
-
*
-
*/
-
public class IterateHashMapExample {
-
public static void main(String[] args) {
-
Map < Integer, String > coursesMap = new HashMap < Integer, String > ();
-
coursesMap.put(1, "C");
-
coursesMap.put(2, "C++");
-
coursesMap.put(3, "Java");
-
coursesMap.put(4, "Spring Framework");
-
coursesMap.put(5, "Hibernate ORM framework");
-
// 4. 使用 Lambda 表达式遍历 HashMap
-
coursesMap.forEach((key, value) -> {
-
System.out.println(key);
-
System.out.println(value);
-
});
-
}
-
}
Output:
-
1
-
C
-
2
-
C++
-
3
-
Java
-
4
-
Spring Framework
-
5
-
Hibernate ORM framework
5. 使用 Stream API 遍历 HashMap
-
package com.java.tutorials.iterations;
-
import java.util.HashMap;
-
import java.util.Map;
-
/**
-
* 在 Java 中遍历 HashMap 的5种最佳方法
-
* @author Ramesh Fadatare
-
*
-
*/
-
public class IterateHashMapExample {
-
public static void main(String[] args) {
-
Map < Integer, String > coursesMap = new HashMap < Integer, String > ();
-
coursesMap.put(1, "C");
-
coursesMap.put(2, "C++");
-
coursesMap.put(3, "Java");
-
coursesMap.put(4, "Spring Framework");
-
coursesMap.put(5, "Hibernate ORM framework");
-
// 5. 使用 Stream API 遍历 HashMap
-
coursesMap.entrySet().stream().forEach((entry) - > {
-
System.out.println(entry.getKey());
-
System.out.println(entry.getValue());
-
});
-
}
-
}
Output:
-
1
-
C
-
2
-
C++
-
3
-
Java
-
4
-
Spring Framework
-
5
-
Hibernate ORM framework
HashMap 的相关教程
- 集合框架-HashMap 类[7]
- 集合框架-LinkedHashMap 类[8]
- 集合框架-TreeMap 类[9]
- 集合框架-EnumMap[10]
- 集合框架-WeakHashMap[11]
- 集合框架-IdentityHashMap[12]
Java中List集合的遍历
1 Iterator迭代器
使用迭代器Iterator进行遍历,这是直接根据List集合的一种自动遍历方式;
-
import java.util.ArrayList;
-
-
public class Demo03 {
-
public static void main(String[] args) {
-
ArrayList<News> list = new ArrayList<News>();
-
-
list.add(new News(1,"list1","a"));
-
list.add(new News(2,"list2","b"));
-
list.add(new News(3,"list3","c"));
-
list.add(new News(4,"list4","d"));
-
-
Iterator<News> iter = list.iterator();
-
while (iter.hasNext()) {
-
News s = (News) iter.next();
-
System.out.println(s.getId()+" "+s.getTitle()+" "+s.getAuthor());
-
}
-
}
-
}
-
-------------------------------------------
-
/**
-
* iterator
-
* 迭代器
-
* @param list
-
*/
-
public static void iteratorTest(List<Integer> list) {
-
long before = System.currentTimeMillis();
-
for (Iterator<Integer> iterator = list.iterator(); iterator.hasNext(); ) {
-
iterator.next();
-
}
-
long after = System.currentTimeMillis();
-
System.out.println("iterator for time=\t" + (after - before));
-
before = System.currentTimeMillis();
-
/**
-
* while 循环写法
-
*/
-
Iterator<Integer> iterator = list.iterator();
-
while (iterator.hasNext()) {
-
iterator.next();
-
}
-
after = System.currentTimeMillis();
-
System.out.println("iterator while time=\t" + (after - before));
-
}
2 for循环
指定下标长度,使用List集合的size()方法,进行for循环遍历,这种遍历方式最基础;
-
import java.util.ArrayList;
-
-
public class Demo01 {
-
/* for循环遍历List集合 */
-
public static void main(String[] args) {
-
ArrayList<News> list = new ArrayList<News>();
-
list.add(new News(1,"list1","a"));
-
list.add(new News(2,"list2","b"));
-
list.add(new News(3,"list3","c"));
-
list.add(new News(4,"list4","d"));
-
for (int i = 0; i < list.size(); i++) {
-
News s = (News)list.get(i);
-
System.out.println(s.getId()+" "+s.getTitle()+" "+s.getAuthor());
-
}
-
}
-
}
3 增强for
使用foreach遍历List,但不能对某一个元素进行操作(这种方法在遍历数组和Map集合的时候同样适用),这种遍历方式较为简洁;
-
import java.util.ArrayList;
-
-
public class Demo02 {
-
/* foreach循环遍历List集合 */
-
public static void main(String[] args) {
-
ArrayList<News> list = new ArrayList<News>();
-
list.add(new News(1,"list1","a"));
-
list.add(new News(2,"list2","b"));
-
list.add(new News(3,"list3","c"));
-
list.add(new News(4,"list4","d"));
-
for (News s : list) {
-
System.out.println(s.getId()+" "+s.getTitle()+" "+s.getAuthor());
-
}
-
}
-
}
4 for-each(java8才支持)
-
/**
-
* foreach
-
* foreach 最慢不推荐 java8 lambda
-
* @param list
-
*/
-
public static void forEachTest(List<Integer> list) {
-
long before = System.currentTimeMillis();
-
list.forEach(item -> {
-
System.out.println(item);
-
});
-
long after = System.currentTimeMillis();
-
System.out.println("list.forEach time=\t" + (after - before));
-
}
5 stream().forEach() 注意java8 才支持
-
/**
-
* stream foreach
-
* stream foreach java8 特有
-
* @param list
-
*/
-
public static void streamForEachTest(List<Integer> list) {
-
long before = System.currentTimeMillis();
-
list.stream().forEach(item -> {
-
System.out.println(item);
-
});
-
long after = System.currentTimeMillis();
-
System.out.println("list.stream().forEach time=\t" + (after - before));
-
}
6 parallelStream().forEach() 注意java8 才支持
-
/**
-
* stream foreach
-
* stream foreach java8 特有
-
* @param list
-
*/
-
public static void parallelStreamForEachTest(List<Integer> list) {
-
long before = System.currentTimeMillis();
-
list.parallelStream().forEach(item -> {
-
System.out.println(item);
-
});
-
long after = System.currentTimeMillis();
-
System.out.println("list.parallelStream().forEach time=\t" + (after - before));
-
}
Java 中 Set 的4中遍历方式
Set 和 List 遍历方式基本一致,Set 没有fori 的遍历方式
主测试方法
-
@Test
-
public void test(){
-
Set<Integer> set = new HashSet<>();
-
int n = 1000_0000;
-
for (int i = 0; i < n; i++) {
-
set.add(i);
-
}
-
System.out.println("======== 1 iterator ==========");
-
iteratorTest(set);
-
System.out.println("======== 2 增强for ==========");
-
forBoostTest(set);
-
System.out.println("======== 3 forEach 最耗时 java8 ==========");
-
forEachTest(set);
-
System.out.println("======== 4 stream forEach 比较耗时和增强for差不多 java8 ==========");
-
streamForEachTest(set);
-
}
-
测试结果
-
======== 1 iterator ==========
-
set.iterator() for time= 68
-
set.iterator() while time= 66
-
======== 2 增强for ==========
-
set.for Boost time= 75
-
======== 3 forEach 最耗时 java8 ==========
-
set.forEach time= 118
-
======== 4 stream forEach 比较耗时和增强for差不多 java8 ==========
-
set.stream().forEach() time= 71
1 迭代器方法
-
/**
-
* 1 iterator
-
* 迭代器
-
* @param set
-
*/
-
public static void iteratorTest(Set<Integer> set) {
-
long before = System.currentTimeMillis();
-
/**
-
* for 循环写法
-
*/
-
for (Iterator<Integer> iterator = set.iterator(); iterator.hasNext(); ) {
-
iterator.next();
-
}
-
long after = System.currentTimeMillis();
-
System.out.println("set.iterator() for time=\t" + (after - before));
-
before = System.currentTimeMillis();
-
/**
-
* while 循环写法
-
*/
-
Iterator<Integer> iterator = set.iterator();
-
while (iterator.hasNext()) {
-
iterator.next();
-
}
-
after = System.currentTimeMillis();
-
System.out.println("set.iterator() while time=\t" + (after - before));
-
}
2 增强for
-
/**
-
*
-
* 增强for
-
* @param set
-
*/
-
public static void forBoostTest(Set<Integer> set) {
-
long before = System.currentTimeMillis();
-
for (int item : set) {
-
System.out.println(item);
-
}
-
long after = System.currentTimeMillis();
-
System.out.println("set.for Boost time=\t" + (after - before));
-
}
3 set.forEach 注意:java8 才支持
-
/**
-
* foreach
-
* foreach 最慢不推荐 java8 lambda
-
* @param set
-
*/
-
public static void forEachTest(Set<Integer> set) {
-
long before = System.currentTimeMillis();
-
set.forEach(item -> {
-
System.out.println(item);
-
});
-
long after = System.currentTimeMillis();
-
System.out.println("set.forEach time=\t" + (after - before));
-
}
4 set.stream().forEach 注意:java8 才支持
-
/**
-
* stream foreach
-
* stream foreach java8 特有
-
* @param set
-
*/
-
public static void streamForEachTest(Set<Integer> set) {
-
long before = System.currentTimeMillis();
-
set.stream().forEach(item -> {
-
// System.out.println(item);
-
});
-
long after = System.currentTimeMillis();
-
System.out.println("set.stream().forEach() time=\t" + (after - before));
-
}
Collection.isEmpty()检测空
使用 Collection.size() 来检测空逻辑上没有问题,但是使用 Collection.isEmpty()使得代码更易读,并且可以获得更好的性能。任何 Collection.isEmpty() 实现的时间复杂度都是 O(1) ,但是某些 Collection.size() 实现的时间复杂度可能是 O(n) 。
反例:
-
if (collection.size() == 0) {
-
...
-
}
正例:
-
if (collection.isEmpty()) {
-
...
-
}
如果需要还需要检测 null ,可采用CollectionUtils.isEmpty(collection)和CollectionUtils.isNotEmpty(collection)。
集合初始化尽量指定大小
Java 的集合类用起来十分方便,但是看源码可知,集合也是有大小限制的。每次扩容的时间复杂度很有可能是 O(n) ,所以尽量指定可预知的集合大小,能减少集合的扩容次数。
反例:
-
int[] arr = new int[]{1, 2, 3};
-
List<Integer> list = new ArrayList<>();
-
for (int i : arr) {
-
list.add(i);
-
}
正例:
-
int[] arr = new int[]{1, 2, 3};
-
List<Integer> list = new ArrayList<>(arr.length);
-
for (int i : arr) {
-
list.add(i);
-
}
字符串拼接使用 StringBuilder
一般的字符串拼接在编译期 java 会进行优化,但是在循环中字符串拼接, java 编译期无法做到优化,所以需要使用 StringBuilder 进行替换。
反例:
-
String s = "";
-
for (int i = 0; i < 10; i++) {
-
s += i;
-
}
正例:
-
String a = "a";
-
String b = "b";
-
String c = "c";
-
String s = a + b + c; // 没问题,java编译器会进行优化
-
StringBuilder sb = new StringBuilder();
-
for (int i = 0; i < 10; i++) {
-
sb.append(i); // 循环中,java编译器无法进行优化,所以要手动使用StringBuilder
-
}
使用String.valueOf(value)代替""+value
当要把其它对象或类型转化为字符串时,使用 String.valueOf(value) 比""+value 的效率更高。
反例:
-
int i = 1;
-
String s = "" + i;
正例:
-
int i = 1;
-
String s = String.valueOf(i);