HashMap使用EntrySet与KeySet的区别(快慢比较),你测试方法对了么?

最近在csdn搜索了关于EntrySet与KeySet的效率问题,发现很多说entrySet快,但是都是好几年前的,而且看他给的源码跟我点开jdk的源码不一致应该是jdk版本不同,另外也有说自己测试结果发现keySet快的,那么到底如何呢?还是得自己验证一下。

我用的是jdk1.8测试的,代码如下

/**
 * 测试Map的keySet和entrySet的性能
 *
 * @author yangbiao
 * @date 2021/1/13 15:31
 */
public class Test {
    HashMap<String,String> map;

    @BeforeEach
    void setUp() {
        map = new HashMap<>();
        for(int i = 0; i <= 1000000; i++){
            map.put("key-" + i, "value-" + i);
        }
    }

    @org.junit.jupiter.api.Test
    void testKeySet() {

        StringBuilder sb = new StringBuilder();
        long startTime = System.currentTimeMillis();
        for( String s : map.keySet()){
            sb.append(s).append(map.get(s));
        }
        long kTime = System.currentTimeMillis() - startTime;

        System.out.println("字符串长度:"+sb.length());

        System.out.println("keySet花费: " + kTime);
    }

    @org.junit.jupiter.api.Test
    void testEntrySet() {
        StringBuilder sb = new StringBuilder();
        long startTime = System.currentTimeMillis();
        for( Map.Entry<String, String> e : map.entrySet()){
            //将map的key和value进行拼接
            sb.append(e.getKey()).append(e.getValue());
        }
        long eTime = System.currentTimeMillis() - startTime;

        System.out.println("字符串长度:"+sb.length());

        System.out.println("entrySet花费: " + eTime);
    }

    @org.junit.jupiter.api.Test
    void testTogether() {
        System.out.println("先测试keySet再测试entrySet");
        testKeySet();
        testEntrySet();
    }

    @org.junit.jupiter.api.Test
    void testTogetherAgain() {
        System.out.println("先测试entrySet再测试keySet");
        testEntrySet();
        testKeySet();
    }

    @org.junit.jupiter.api.Test
    void testTogetherBy2Thread() throws InterruptedException {
        //创建两个线程分别测试
        Thread thread1 = new Thread(this::testKeySet);
        Thread thread2 = new Thread(this::testEntrySet);
        thread1.start();
        thread2.start();
        Thread.sleep(4000);
    }

    @org.junit.jupiter.api.Test
    void testTogetherBy2ThreadAgain() throws InterruptedException {
        //创建两个线程分别测试
        Thread thread1 = new Thread(this::testEntrySet);
        Thread thread2 = new Thread(this::testKeySet);
        thread1.start();
        thread2.start();
        Thread.sleep(4000);
    }
}

定义一个HashMap,每个测试方法都初始化一次,有6个测试方法,分别是测试keySet,entrySet,keySet+entrySet,entrySet+keySet,keySet+entrySet两个线程执行,entrySet+keySet两个线程执行。

为什么要这样写测试方法,因为我发现网上给的很多测试是在同一个方法里进行测试的,我就交换了下顺序,发现结果竟然是后面的总是慢于前面的。这或许是java编译器优化了?我也不清楚。单个方法进行测试结果会有误差不好判断,所以方法1和2的结果都没有参考性可言。

运行方法3和4即testTogether()testTogetherAgain()是截然相反的结果。
在这里插入图片描述
在这里插入图片描述

运行方法5和6即testTogetherBy2Thread()testTogetherBy2ThreadAgain(),用两个线程不同加入顺序执行测试。
在这里插入图片描述
在这里插入图片描述
表明entrySet略快于keySet,再增加一倍的数据,测试如下
在这里插入图片描述
在这里插入图片描述
证明entrySet快于keySet

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: HashMapEntrySet区别在于 HashMap 是一种键值对映射表,它存储关键字和值之间的映射关系;而 EntrySetHashMap 中所有键值对的集合,它可以用来访问 HashMap 中的所有键值对。 ### 回答2: HashMapEntrySetJava中的两个不同的概念。 1. HashMapJava中的一个数据结构,它是一个基于哈希表的Map接口的实现类。它允许存储键值对,并根据键的哈希值进行快速查找。HashMap的特点是键值对的存储是无序的。 2. EntrySetHashMap中的一个方法,它返回一个包含所有键值对(Entry)的Set集合。每个Entry对象表示一个键值对,包括键和对应的值。EntrySet的返回结果是无序的。 区别: - HashMap是一个数据结构,而EntrySetHashMap提供的一个方法。 - HashMap用于存储键值对,而EntrySet用于获取HashMap中存储的所有键值对。 - HashMap中的键值对是无序存储的,而返回的EntrySet也是无序的。 使用HashMap时,可以通过调用EntrySet方法来获取HashMap中存储的所有键值对,进而对键值对进行处理,比如遍历所有的键值对。这样可以方便地对HashMap中的数据进行操作。 ### 回答3: HashMapJava 中的一种数据结构,它是基于哈希表实现的,用于存储键值对。它允许我们通过键来快速检索和访问值,其底层实现是使用数组和链表/红黑树。 EntrySetHashMap 的一个方法,它返回一个包含所有键值对映射的 Set 集合。每个键值对都是 HashMap 中的一个 Entry 对象,它包含了键和值的引用。EntrySet 可以用来遍历 HashMap 中的所有键值对。 HashMapEntrySet区别如下: 1. 数据结构:HashMap 是一个类,是存储键值对的数据结构。而 EntrySetHashMap 的一个方法,用于获取所有键值对的集合。 2. 存储方式:HashMap 使用哈希表来存储数据,通过键的哈希值来确定存储位置。而 EntrySet 仅是一个集合,存储了 HashMap 中的所有键值对。 3. 检索方式:HashMap 允许通过键来快速检索和访问值,可以使用 get() 方法根据键获取值。而 EntrySet 是用于遍历所有键值对的,需要使用循环来逐个获取键值对。 4. 作用:HashMap 主要用于存储和管理键值对的数据,提供了一系列的操作方法,如 put() 和 get()。而 EntrySet 可以用于遍历 HashMap 的所有键值对,进行操作或者获取键值对的信息。 总结来说,HashMap 是一种数据结构,用于存储键值对,而 EntrySetHashMap 的一个方法,用于获取所有键值对的集合。EntrySet 可以通过遍历获取 HashMap 中的所有键值对,进行操作或者获取键值对的信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值