java8特性之forEach篇

article/2025/7/28 7:17:11

java8特性之forEach篇

  • forEach介绍
  • 使用条件
  • 迭代原理
  • 性能

forEach介绍

forEach是java8的特性之一,它可以大大简化代码的操作,比如有关HashMap的操作:

HashMap<Integer, String> hashMap = new HashMap<>(3);
hashMap.put(1, "张三");
hashMap.put(2, "李四");
hashMap.put(3, "王五");
for (Map.Entry<Integer, String> entry : hashMap.entrySet()) {System.out.println(entry.getKey() + "," + entry.getValue());
}

这是使用映射的视图来遍历整个hashmap来输出键值对的逻辑,输出如下:

写起来比较繁琐,看起来也有点累,那么使用forEach就可以简化为如下代码:

Map<Integer, String> hashMap = new HashMap<>(3);
hashMap.put(1, "张三");
hashMap.put(2, "李四");
hashMap.put(3, "王五");
hashMap.forEach((k, v) -> System.out.println(k + "," + v));

可以发现,它简化了大部分的操作。那么我们就会有几个问题,比如什么情况下可以使用forEach,以及它的底层迭代原理是什么,性能跟传统的foreach相比如何等。

使用条件

点进forEach方法中,可以发现,它是Iterable接口的一个方法,因此可以得出一个结论,只要一个类实现了此接口,那么此类的实例一定可以使用forEach方法。

同时我们可以看到,Collection接口继承了此接口。而我们大部分的集合类接口都继承了Collection接口,具体有Set、List、SortedSet、HashSet、TreeSet、ArrayList、LinkedList、 Vector、Collections、Arrays、AbstractCollection。所以只要是上述的实现类,都可以使用forEach方法。

迭代原理

让我们回归Iterable接口,看看接口中的方法:

default void forEach(Consumer<? super T> action) {Objects.requireNonNull(action);for (T t : this) {action.accept(t);}
}

方法的形参是一个Consumer类型的action,我们可以猜到,这一定是跟lambda表达式相关的一个东西。事实上,它是一个函数式接口,让我们看看Consumer:

@FunctionalInterface
public interface Consumer<T> {/*** 可实现方法,接受一个参数且没有返回值** @param t the input argument*/void accept(T t);/*** 返回一个组合的{@code consumer},该组合的{@code consumer}按顺序执行此操作,然后执行     * {@code after}操作。如果执行任一操作时引发异常,则将其中继到组合操作的调用方。如果执行此操作       * 引发异常,则{@code after}操作将不会执行。** @param after the operation to perform after this operation* @return a composed {@code Consumer} that performs in sequence this* operation followed by the {@code after} operation* @throws NullPointerException if {@code after} is null*/default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };}
}

因此实际上,它还是使用了foreach来遍历迭代对象,在一个个对参数执行对应的操作。

性能

为了测试性能,我们可以编写一个循环,来输出遍历完的时间,具体如下:

public static void main(String[] args) {List<Integer> list = new ArrayList<>();for (int i = 0; i < 100000; i++) {list.add(i);}long l = System.currentTimeMillis();list.forEach(i -> {});System.out.println(System.currentTimeMillis() - l);
​l = System.currentTimeMillis();for (Integer s : list) {}System.out.println(System.currentTimeMillis() - l);
}

输出结果如下:

大约相差了十五倍。那么为什么.forEach就会比foreach慢了个十倍左右的数量级呢?细细比较两者区别可以想到forEach多了一个Consumer的声明,那么我们再来测试一下:

public static void main(String[] args) {List<Integer> list = new ArrayList<>();for (int i = 0; i < 100000; i++) {list.add(i);}// 声明Consumerlong l = System.currentTimeMillis();Consumer<Integer> consumer = integer -> {};System.out.println(System.currentTimeMillis() - l);// forEachl = System.currentTimeMillis();list.forEach(consumer);System.out.println(System.currentTimeMillis() - l);// foreachl = System.currentTimeMillis();for (Integer integer : list) {}System.out.println(System.currentTimeMillis() - l);
}

输出结果如下:

确实可以得出结论:forEach相比较foreach10倍级的开销大部分都消耗在了实例化Consumer上,迭代器本身并没有什么区别。

但forEach效率真的这么低吗?

其实不是的,java会使用预热,当第二次第三次调用forEach的时候,速度不比foreach慢,有可能跟JIT有关。


http://chatgpt.dhexx.cn/article/LPmMtIQS.shtml

相关文章

java8特性快速对list集合的筛选过滤和计算

java8特性快速对list集合的筛选过滤和计算 一、准备工作 1.创建一个Student对象 package com.shiro.test.java8特性;import java.io.Serializable;/*** 学生的实体类*/ public class Student implements Serializable {private String id;private String username;private In…

Java8特性大全(最新版)

一、序言 Java8 是一个里程碑式的版本&#xff0c;凭借如下新特性&#xff0c;让人对其赞不绝口。 Lambda 表达式给代码构建带来了全新的风格和能力&#xff1b;Steam API 丰富了集合操作&#xff0c;拓展了集合的能力&#xff1b;新日期时间 API 千呼万唤始出来&#xff1b;…

Java 8特性之Optional详解

一、Optional类 简介 Optional类是 Java 8 引入的一个很有趣的特性。它主要解决的问题是臭名昭著的空指针异常&#xff08;NullPointerException&#xff09; Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true&#xff0c;调用get()方法会返回…

Java基础之java8 新特性

Java基础之java8 新特性 一、Lambda 表达式二、Stream 初体验三、方法引用四、默认方法五、Optional 类六、Base 64七、字符串拼接八、 equals 与 instanceof九、final 一、Lambda 表达式 Lambda 表达式是在 Java8 中引入的&#xff0c;并号称是 Java8 的最大的特点。Lambda 表…

java8新特性Lambda和Stream以及函数式接口等新特性介绍

主要内容 1.Lambda 表达式 2.函数式接口 3.方法引用与构造器引用 4.Stream API 5.接口中的默认方法与静态方法 6.新时间日期API 7.其他新特性 Java 8新特性简介 速度更快速度更快代码更少&#xff08;增加了新的语法Lambda 表达式&#xff09;强大的Stream API便于并行最大化…

python 读取并显示图片的两种方法

转自&#xff1a;http://www.cnblogs.com/yinxiangnan-charles/p/5928689.html 在 python 中除了用 opencv&#xff0c;也可以用 matplotlib 和 PIL 这两个库操作图片。本人偏爱 matpoltlib&#xff0c;因为它的语法更像 matlab。 一、matplotlib 1. 显示图片 import matplotli…

Python同时显示多张图片在一个画面中(两种方法)

很多时候需要把很多图片同时显示到一个画面中&#xff0c;现在分享两个方法&#xff0c;这里我恰好拿之前写的爬取网上图片保存到本地的爬虫模型爬一些图片作为素材Python 爬虫批量爬取网页图片保存到本地。 得到素材如下所示&#xff1a; 现在让这些图片同时显示。 方法一 …

python 打开 显示图片

import matplotlib.pyplot as plt # plt 用于显示图片 from PIL import Imageplt.figure() plt.plot([1,2], [1,2])plt.rcParams[font.sans-serif] [SimHei] # 中文乱码 plt.imshow(Image.open("b.png"))plt.axis(off)plt.tight_layout() manager plt.get_current…

python 把matplotlib绘制的图片显示到html中

需求 一般网页中图片显示是给url链接过去&#xff0c;但是有的时候显示的图表是临时计算绘制的&#xff0c;并不需要保存&#xff0c;因此就需要直接显示一个图片的方法。 灵感是来自于jupyter&#xff0c;发现他是这样的&#xff1a; 估计是base64编码了。 查了一下如何把ma…

python如何将图片显示在网页上

from flask import Flask, render_template_string import base64 import cv2import osapp Flask(__name__)# 读取图像app.route(/)def index():# 读取图像文件并将其转换为Base64编码的字符串img_path 1.pngimg_data open(img_path, rb).read()img_base64 base64.b64encod…

python matplotlib 显示图像

python matplotlib 显示图像 首先需要import import os from PIL import Image import matplotlib.pyplot as plt 显示一幅彩色图片 img Image.open(os.path.join(images, 2007_000648 .jpg))plt.figure("Image") # 图像窗口名称 plt.imshow(img) plt.axis(on)…

python中plt.imshow()不显示图片

python画图函数可能是需要一些设置&#xff0c;或者一些特定的函数运行才会出现图片的。 Python中plt.imshow(image)无法显示图片解决办法 使用plt.imshow()发现不能显示图片&#xff0c;加了plt.show()也还是不能显示 先引入包pylab import pylab 然后在plt.imshow(img)后面…

Python tkinter之PhotoImage图片显示问题

作为Python小白的你&#xff0c;有没有遇到过这几个问题&#xff1f; PhotoImage不支持jpg等图片格式&#xff1b;将PhotoImage放在函数里图片不显示&#xff1b;循环加入图片只显示一张&#xff1b; 这些难倒了一大批小白&#xff0c;那么接下来&#xff0c;本文教你如何解决…

python图显示在新的窗口_python在新的图片窗口显示图片(图像)的方法

python在新的图片窗口显示图片(图像)的方法 使用python画图,发现生成的图片在console里。不仅感觉很别扭,很多功能也没法实现(比如希望在一幅图里画两条曲线)。 想像matlab一样单独地生成一个图片窗口,然后我在网上找了一个多小时,都没有找到想要的,要么仅仅是画图的教…

python人工智能-动态显示图片的几种办法实现

python人工智能动态显示图片 任务简介&#xff0c;在电脑创建一个文件加&#xff0c;利用代码往文件加入照片文件&#xff0c; 然后动态显示该文件夹中的照片&#xff0c;显示给用户观看&#xff0c;可以利用open-cv&#xff0c;matplotlib,PIL等技术实现 这里是电脑一个装有照…

Python 3 显示图像的方法

如果你正在寻找一个库来帮助你在 Python 中显示图像&#xff0c;那么你很幸运。Python 有许多不同的库可用于显示图像。三个最受欢迎的库是Pickel、Matplotlib 和 OpenCV。 到底应该选哪一个&#xff0c;还是看自己的个人喜好了。我喜欢并使用 OpenCV 而不是 Pillow 和 Matplot…

python显示图片_python图像显示

广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 使用python进行数字图片处理,还得安装pillow包。 虽然python里面自带一个pil(python images library), 但这个库现在已经停止更新了,所以使用pillow, 它是由p…

python显示图片

python显示图片两种方法 1.利用Pillow包 未安装的可以通过pip install Pillow安装 from PIL import Image img Image.open(notMNIST_large/A/aGFua28udHRm.png) img.show() 显示的图片如下&#xff1a; 2.利用matplotlib 同样可以通过pip进行安装 from PIL import Image …

使用Python查看并显示图像

今天又来写一个Python的基础用法&#xff0c;使用Python来显示图像&#xff0c;不多说&#xff0c;代码如下&#xff1a; import matplotlib.pyplot as plt from matplotlib.image import imreadimg imread(C:/Users/xx/Desktop/xx.jpg) plt.imshow(img)plt.show() 2022.05.1…

基于python多光谱遥感数据处理、图像分类、定量评估及机器学习方法应用

普通数码相机记录了红、绿、蓝三种波长的光&#xff0c;多光谱成像技术除了记录这三种波长光之外&#xff0c;还可以记录其他波长&#xff08;例如&#xff1a;近红外、热红外等&#xff09;光的信息。与昂贵、不易获取的高光谱、高空间分辨率卫星数据相比&#xff0c;中等分辨…