hashmap1.8新增遍历方法forEach与之前版本遍历方式的性能比较

对于遍历hashmap的方法,总结下来分别为以下:
a.得到Set对象,再使用增强for循环遍历
b.使用迭代器遍历
c.1.8以上的都可以使用set对象的foreach方法遍历

猜测:a的for循环底层调用的是迭代器,因此a和b的性能应该相似
c中虽然用的不是迭代器,但是原理与迭代器一样所以c应该性能与a,b相似
下面附上迭代器的源码
这是方法入口,调用了nextNode方法
hashmap1.8新增遍历方法forEach与之前版本遍历方式的性能比较_第1张图片
使用迭代器最重要的代码就是最后一个if判断。如果一时间想不通如何实现的可以查一下他的实现原理。

接下来附上forEach的源码
hashmap1.8新增遍历方法forEach与之前版本遍历方式的性能比较_第2张图片
发现他遍历数据的顺序与原理跟迭代器是一样的。因此有了上面的猜测

接下来进行测试:

	HashMap m = new HashMap();
			for (int i = 0 ; i  < 10000000 ; i++) {
				String s = "a" + i;
				m.put("b" + i, s);
			}
			long t1 = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
			Set> set = m.entrySet();
			for (Entry e : set) {
				System.out.println(e.getKey() + "=" + e.getValue());
			}
			long t2 = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();





			long t3 = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
			Iterator i = m.entrySet().iterator();
			while (i.hasNext()){
				Map.Entry entry = (Entry) i.next();
				System.out.println(entry.getKey() + "=" + entry.getValue());
			}
			long t4 = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();


			long t5 = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
			m.entrySet().forEach(new Consumer>() {
				@Override
				public void accept(Entry stringStringEntry) {
					System.out.println(stringStringEntry.getKey() + "=" + stringStringEntry.getValue());
				}
			});
			long t6 = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
			System.out.println("使用for循环遍历时间:" + (t2 - t1));
			System.out.println("使用迭代器遍历时间:" + (t4 - t3));
			System.out.println("使用forEach遍历时间:" + (t6 - t5));

测试结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
测试了3次

发现,三者性能基本相同,至于上面结果中for循环遍历时间长一点的原因是他被放在第一个。经过测试放在第一个遍历的时间都会长一点。

你可能感兴趣的:(hashmap1.8新增遍历方法forEach与之前版本遍历方式的性能比较)