在 Java 中遍历 HashMap 的5种最佳方式

参考链接:

java 中 List 的5种遍历方式
Java 中 Set 的4中遍历方式
Java 中 Map 的5种遍历方式

在 Java 中遍历 HashMap 的5种最佳方式

2020-03-14 10:41·骇客与画家

原文地址:
https://www.javaguides.net/2020/03/5-best-ways-to-iterate-over-hashmap-in-java.html[1]

作者:Ramesh Fadatare[2]

翻译:高行行

在本文中,我们将通过示例讨论在 Java 上遍历 HashMap[3] 的五种最佳方法。

  1. 使用 Iterator 遍历 HashMap EntrySet
  2. 使用 Iterator 遍历 HashMap KeySet
  3. 使用 For-each 循环迭代 HashMap
  4. 使用 Lambda 表达式[4]遍历 HashMap
  5. 使用 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()检测空

消灭 Java 代码的“坏味道”

使用 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);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要了解 Java 的 Map 遍历最佳方法,首先需要理解 Java Map 的概念。Map 是 Java 编程语言实现映射(Mapping)的对象。与 List 的元素按照顺序存储不同,Map 存储的是键值对(Key-Value Pair),其每个键只能出现一次。Java Map 的实现有很多,例如 HashMap、LinkedHashMap、TreeMap 等。Map 的数据可以使用 key-value 的方式访问,这使得 Map 在 Java 非常有用。 在实现 Map 遍历的过程Java 提供了多方法,可以选择使用最适合自身需求的方法,具体如下: 1. 使用 for-each 循环遍历 Map:此方法是最常见的遍历 Map 的方式,可以使用 for-each 循环遍历 Map 的所有元素,但不能同时访问 key 和 value。 代码示例: ``` Map<String, Integer> map = new HashMap<>(); for (Map.Entry<String, Integer> entry : map.entrySet()) { System.out.println(entry.getKey() + ":" + entry.getValue()); } ``` 2. 使用 Iterator 遍历 Map:通过使用 Iterator,我们可以同时访问 Map 的 key 和 value。这方法处理大量数据时更加有效,因为在处理数据时可以省略一些不必要的对象创建和销毁操作。 代码示例: ``` Map<String, Integer> map = new HashMap<>(); Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<String, Integer> entry = iterator.next(); System.out.println(entry.getKey() + ":" + entry.getValue()); } ``` 3. 使用 Lambda 表达式遍历 Map:Lambda 表达式是 Java 8 新增的特性,可以大大简化代码的编写。使用 Lambda 表达式遍历 Map,可以同时访问 key 和 value,但比起前两方法来说代码量更加简洁。 代码示例: ``` Map<String, Integer> map = new HashMap<>(); map.forEach((key, value) -> { System.out.println(key + ":" + value); }); ``` 综上所述,以上三方法都可以实现 Map 的遍历,可以根据具体需求选择最适合自身的方法。同时,为了提高效率,可以使用 Iterator 或 Lambda 表达式来遍历大量元素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值