Java(36):Lambda 与 Stream 小结

Java泛型、Lambda与多线程常见问题解析 本文深入解析Java中泛型方法冲突、Lambda表达式与匿名类区别、函数式接口定义、线程同步机制及流操作等核心知识点,涵盖编译问题、语法差异、并发控制及流式处理等内容,帮助开发者理解Java语言的关键特性与常见陷阱。 阅读详情

2018年10月22日

目录

一、Lambda 

1.1 lambda小例子1

1.2 lambda小例子2

1.3 分析

二、Stream

2.1 如何理解Stream

2.2 Stream特点

2.3 生成Stream的方式

2.4  Stream的中间操作

2.5  Stream的终止操作



Java 是面向对象语言,除了原始数据类型之处,Java 中的所有内容都是一个对象。而在函数式语言中,我们只需要给函数分配变量,并将这个函数作为参数传递给其它函数就可实现特定的功能。

一、Lambda 

Lambda 表达式的加入,使得 Java 拥有了函数式编程的能力。在其它语言中,Lambda 表达式的类型是一个函数;但在 Java 中,Lambda 表达式被表示为对象,因此它们必须绑定到被称为功能接口的特定对象类型。

1.1 lambda小例子1

		new Thread(() -> System.out.println("hello!!")).start();;

输出结果:

hello!!

点击“->”:

 

1.2 lambda小例子2

package LambdaTest;

public  class Lambda2 {
	interface  ITest  { //接口
		int test(String  string);
	}


	static void Print(ITest test) {//接口做对象
		test.test("hello world");
	}


	public static void main(String [] args) {
		Print(string -> {System.out.println(string);
		return 0;}
		);
   }
}

运行结果:

hello world

 

1.3 分析

先来看lambda表达式的语法:

() -> {}
  1. () : 括号就是接口方法的括号,接口方法如果有参数,也需要写参数。只有一个参数时,括号可以省略。(Thread的构造函数接收的是一个Runnable接口对象,而我们这里的用法相当于是把一个函数当做接口对象传递进去了,这点理解很关键,这正是函数式编程的含义所在。)

  2. -> :这个箭头是lambda表达式的关键操作符,分割左右部分的,没啥好讲的,作用是:把表达式分成两截,前面是函数参数,后面是函数体。

  3. {} : 要实现的方法体。只有一行代码时,可以不加括号,可以不写return。

  4. 我们注意到Runnable有个注解 @FunctionalInterface,它是jdk8才引入,它的含义是函数接口。它是lambda表达式的协议注解,这个注解非常重要,后面做源码分析会专门分析它的官方注释,到时候一目了然。

 

二、Stream

 

2.1 如何理解Stream

    Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。
    简单来说,它的作用就是通过一系列操作将数据源(集合、数组)转化为想要的结果。

 

2.2 Stream特点

   Stream 是不会存储元素的。
    Stream 不会改变原对象,相反,他们会返回一个持有结果的新Stream。
    Stream 操作是延迟执行的。意味着它们会等到需要结果的时候才执行。

 

2.3 生成Stream的方式

下面是五种生成stream方法:

		//1. Collection系的 stream() 和 parallelStream();
		ArrayList<Object> list = new ArrayList<>();
		Stream<Object> stream = list.stream();
		Stream<Object> stringStream = list.parallelStream();
		
		//2. 通过Arrays
		Stream<String> stream1 = Arrays.stream(new String[10]);
		
		//3. 通过Stream
		Stream<Integer> stream2 = Stream.of(1,2,3);
		
		//4. 无限流,迭代
		Stream<Integer> iterate = Stream.iterate(0, (x) -> x+22);
		iterate.limit(10).forEach(System.out::println);
		
		//5. 生成
		Stream<Double> generate = Stream.generate(() -> Math.random());
		generate.forEach(System.out::println);
		

 

2.4  Stream的中间操作

		//和map差不多,但返回类型为Stream,类似list.add()和list.addAll()的区别
//		arrayList.stream().map(s -> s+1).forEach(System.out::println);
		arrayList.stream()
		        .map(s -> s + 1)  //映射
		        .flatMap(s -> Stream.of(s)) 
		        .filter(s -> s < 1000)    //过滤
		        .limit(5)   //限制
		        .skip(1)    //跳过
		        .distinct() //去重
		        .sorted()   //自然排序
		        .sorted(Integer::compareTo) //自定义排序
        ;

多个中间操作连接而成为流水线,流水线不遇到终止操作是不触发任何处理的,所为又称为“惰性求值”。

关于map方法,参数为一个Function函数型接口的对象,也就是传入一个参数返回一个对象。这个参数就是集合中的每一项。类似Iterator遍历。其它的几个操作思想都差不多。

执行上面的方法没什么用,因为缺少终止操作。

 

2.5  Stream的终止操作

1.stream常用api

		// 返回流中元素的总个数
		System.out.println(arrayList.stream().count());
		arrayList.stream().allMatch((x) -> x == 555); // 检查是否匹配所有元素
		arrayList.stream().anyMatch(((x) -> x>600)); // 检查是否至少匹配一个元素
		arrayList.stream().noneMatch((x) -> x>500); //检查是否没有匹配所有元素
		arrayList.stream().findFirst(); // 返回第一个元素
		arrayList.stream().findAny(); // 返回当前流中的任意一个元素
		arrayList.stream().count(); // 返回流中元素的总个数
		arrayList.stream().forEach(System.out::println); //内部迭代
		arrayList.stream().max(Integer::compareTo); // 返回流中最大值
		Optional<Integer> min = arrayList.stream().min(Integer::compareTo);//返回流中最小值
		System.out.println("min "+min.get());

 

2.reduce (归约):将流中元素反复结合起来得到一个值

		Integer reduce = arrayList.stream()
		        .map(s -> (s + 100))
		        .reduce(0, (x, y) -> x + y);    
        //归约:0为第一个参数x的默认值,x是计算后的返回值,y为每一项的值。
		System.out.println(reduce);
		
		Optional<Integer> reduce1 = arrayList.stream()
		        .map(s -> (s + 1))
		        .reduce((x, y) -> x + y); 
		// x是计算后的返回值,默认为第一项的值,y为其后每一项的值。
		System.out.println(reduce1);
		

 

3.collect(收集):将流转换为其他形式。需要Collectors类的一些方法。

        Set<Integer> collect = arrayList.stream()
                .collect(Collectors.toSet());
        System.out.println(collect);
        
        List<Integer> collect1 = arrayList.stream()
                .collect(Collectors.toList());
        System.out.println(collect1);

        HashSet<Integer> collect2 = arrayList.stream()
                .collect(Collectors.toCollection(HashSet::new));
        System.out.println(collect2);
        
        //分组 {group=[444, 555, 666, 777, 555]}
        Map<String, List<Integer>> collect3 = arrayList.stream()
                .collect(Collectors.groupingBy((x) -> "group"));//将返回值相同的进行分组
        System.out.println(collect3);

        //多级分组 {group={777=[777], 666=[666], 555=[555, 555], 444=[444]}}
        Map<String, Map<Integer, List<Integer>>> collect4 = arrayList.stream()
                .collect(Collectors.groupingBy((x) -> "group", Collectors.groupingBy((x) -> x)));
        System.out.println(collect4);

        //分区 {false=[444], true=[555, 666, 777, 555]}
        Map<Boolean, List<Integer>> collect5 = arrayList.stream()
                .collect(Collectors.partitioningBy((x) -> x > 500));
        System.out.println(collect5);

        //汇总
        DoubleSummaryStatistics collect6 = arrayList.stream()
                .collect(Collectors.summarizingDouble((x) -> x));
        System.out.println(collect6.getMax());
        System.out.println(collect6.getCount());

        //拼接 444,555,666,777,555
        String collect7 = arrayList.stream()
                .map(s -> s.toString())
                .collect(Collectors.joining(","));
        System.out.println(collect7);

        //最大值
        Optional<Integer> integer = arrayList.stream()
                .collect(Collectors.maxBy(Integer::compare));
        System.out.println(integer.get());

 

Java,Lambda,Stream实例 package com.main; import java.util.*; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { // write your code here List&lt;String&gt;... 阅读详情

相关推荐

【随机过程】Markov Chain的定义及发展历程与实际应用

本模块书写的初衷:由于在学习张波张景肖等学者所著的《应用随机过程》存在着不甚了解的知识点,经过个人查找资料并整理、分享,希望能够为有同样疑惑的读者贡献绵薄之力,同时如果个人编写内容有错误,恳请读者指正。本文为对《应用随机过程》第42页中Markov Chain基本概念的补充。1.Markov Chain的定义俄国数学家 Andrey Andreyevich Markov 研究并提出一个用数学方法就能解释自然变化的一般规律模型,被命名为马尔科夫链(Markov Chain)。

qq_49657150的博客 3743

万字详解Stream流以及Lambda(看这一篇就够用)

Stream流和Lambda表达式是Java 8中的两个重要特性,它们可以使得代码更加简洁、可读、灵活,同时可以提高代码的效率和可维护性。如果您还没有使用过Stream流和Lambda表达式,那么希望这篇教程能够帮助您入门。

Sunshineづ 3130

RK3588 C-PHY摄像头驱动升级踩坑记:从‘Only CSI2 supported’报错到成功取流

本文详细记录了在RK3588平台上调试C-PHY摄像头驱动的全过程,从‘Only CSI2 supported’报错分析到成功取流。内容涵盖C-PHY与CSI-2协议差异、SDK版本对比、V4L2框架下的bus-type解析机制,以及硬件排查与寄存器调优实战经验,为嵌入式Camera驱动工程师提供宝贵参考。

weixin_42522374的博客 123

【Lambda】java之lambda表达式&stream流式编程操作集合

Java之lambda表达式及stream流编程操作

Hanson的博客 1336

图解B树的原理及操作

本文主要参考:https://blog.youkuaiyun.com/shenchaohao12321/article/details/83243314 1. B树 1.1 B树的定义 B树也称B-树,它是一颗多路平衡查找树。我们描述一颗B树时需要指定它的阶数,阶数表示了一个结点最多有多少个孩子结点,一般用字母m表示阶数。当m取2时,就是我们常见的二叉搜索树。 一颗m阶的B树定义如下: 1)每个结点最多有m-1个关键字。 2)根结点最少可以只有1个关键字。 3)非根结点至少有Math.ceil(m/2)-

jinking01的专栏 3万+

【Unity实战100例】Unity循环UI界面切换卡片功能

功能包括:可以设置半径,高度,速度,元素数量用户可以根据自己的实际需求接入 制作思路:创建每个元素对应的虚拟点,通过旋转管理这些虚拟点,然后把旋转信息和位置信息同步给实际的元素

纯技术流日常开发商业开发记录总结等 7717

【Java Lambda系列】一文弄懂Stream API

在开发项目的中,集合是我们最常用的数据结构之一!但Java8以前,集合的操作并不算很好,比如:分组、取最大值,收集对象的某个属性等,我们一般通过SQL的语法来过滤,或通过Java中for循环的进行处理,这种方式还是蛮恼火的。估计Java8的设计者也知晓这种问题吧,所以才会为我们带来Stream(流)。本章将Stream结合之前的Lambda语法进行阐述,希望通过本章阅读,不仅学习Stream流相关的骚操作,而且还能对Lambda运用更加熟练!

uu的博客 758

基于STM32的IMU惯性/姿态解算与多参数上位机可视化实现_资料编号38

本项目实现基于STM32F103C8T6标准库,对姿态/惯性(IMU)传感器姿态解算,通过USB-TTL转串口模块将姿态角/欧拉角、加速度、角速度、磁场、气压、海拔高度、磁力计温度、气压计温度等数据显示在PC端上位机,系统采用可充电锂电池供电。

嵌入式阿齐Archie 1万+

Java 基础 —— Java 8 新特性 stream 与 Lambda

一、Stream 简介 Java 8 引入了全新的 Stream API,这里的 Stream 和 I/O 流不同,它更像具有 Iterable 的集合类,但行为和集合类又有所不同。Stream 是 Java 8 的新特性,是对容器对象功能的增强,它专注于对容器对象进行各种非常便利、高效的聚合操作(aggregate operation)或者大批量数据操作。Stream 是用函数式编程方式在集合类上进行复杂操作的工具,开发者可以更容易地使用 Lambda 表达式,并且更方便地实现对集合的查找、遍历、过滤以及

IT__learning的博客 2172

1. 在 SAP ABAP 事物码 SEGW 里创建 SAP OData 项目

本文介绍如何在 SAP ABAP 事物码 SEGW 里创建 SEGW 项目,使用工具生成 Runtime 运行时需要的资源。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 5442

第8讲:基于CST PCB Studio的电源完整性仿真(IR Drop + PDN)

本文系统介绍了电源完整性(PI)仿真的两大核心模块:直流IRDrop仿真与交流PDN阻抗仿真。文章详细阐述了两种仿真的原理、算法(PEEC和3DFE-FD)及完整操作流程,包括参数配置、软件实操步骤和常见问题解决方案。IRDrop仿真用于分析直流供电压降问题,PDN仿真则针对高频电源噪声和谐振问题。文中还提供了优化建议和故障排查方法,如调整铜箔厚度、优化电容布局等,为高速数字系统的电源完整性设计提供了全面的技术指导。(149字)

一只豌豆象的博客 235

Lambda表达式和Stream流

Lambda表达式语法详解,底层实现原理,Lambda和匿名内部类的对比,StreamAPI,Stream常用方法

KANYEA的博客 771

【箱子之字形摆放】python实现-附ChatGPT解析

箱子之形摆放有一批箱子(形式为宁符串,设为str) ,要求将这批箱子按以之形的顺序摆放在宽度为n的空地,请输出箱子的摆放结果。例如:箱子为ABCDEFG,空地宽度为3,摆放结果如图:则输出结果为:AFGBECD输入一行字符串,通过空格分制,前面部分为字母或数字组成的字符串str,表示;后面部分为一个数字n,表示。ABCDEFG 3箱子摆放结果,如题目示例所示AFGBECD。

sinat_29950703的博客 370

Lambda表达式和Stream流执行流程

Data;@Data/*** @param <E1>构造方法第一个参数类型* @param <E2>构造方法第二个参数类型* @param <E3>构造方法第三个参数类型* @param <E4>构造方法第四个参数类型* @param <E5>构造方法第五个参数类型* @param <T>最后一个泛型是构造方法所属的类型*/

HTDiiii的博客 1002

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Lambda 和 Stream API

Lambda 表达式 Java 8 开始,可以用 Lambda 表示只有一个抽象方法的接口(函数式接口,该类型的接口一般标有 @FuntionalInterface 注解)。此前我们只能通过繁琐的匿名实现类表示。 比如,Runnable 接口就是一个函数式接口。 所以我们可以用 Lambda 表达式创建一个该接口的匿名实现。 () 表示函数式接口中定义的抽象方法的参数,因为 Runnable 接口中的 run() 方法没有参数,所以用空的 () 表示。 箭头后的内容表示该方法的实现,这里就是指 void

FangHX25的博客 365

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Java8新特性 Lambda、Function和Stream

java8新特性

qq_44620773的博客 759

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

36. 【Java】Lambda 表达式:函数式编程的入口

本文深入讲解Java 8引入的Lambda表达式,从匿名内部类的痛点出发,详细解析Lambda的基本语法、函数式接口、方法引用等核心概念。

gugucoding的博客 431

Java1.8之Lambda表达式、流Stream学习

1、什么是函数式编程? 答:每个人对函数式编程的理解不尽相同。但其核心是:在思考问题时,使用不可变值和函数,函数对一个值进行处理,映射成另一个值。 2、Java 8的最大变化是引入了Lambda表达式——一种紧凑的、传递行为的方式。 答:和使用匿名内部类的另一处不同在于声明参数的方式。使用匿名内部类时需要显式地声明参数类型,而在Lambda表达式中无需指定类型,程序依然可以编译。这是因为javac根据程序的上下文在后台推断出了参数的类型。这意味着如果参数类型不言而明,则无需显式指定。   尽管与之前相

Biexiansheng的博客 403

Java中stream是什么?有什么作用?如何使用?

在Java中,Stream(流)是一种用于操作集合(Collection)、数组等数据源的API。它提供了一种功能强大且表达力高的编程模型,可以用更简洁、更具可读性的方式处理数据。Stream的主要作用是进行数据的转换、筛选、聚合等操作,可以极大地简化对数据的处理。使用Stream可以避免显式地使用迭代器或循环来操作集合,提高代码的可读性和简洁性。stream()在上述示例中,我们首先获取了一个整数列表作为数据源。然后,通过调用stream()方法获取了一个数据流。接着,使用中间操作filter()

热爱技术,享受生活 2万+

第36讲 Stream流

Java8以后 API添加了一个新的抽象称为流Stream,Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java运算和表达的高阶抽象。将要处理的元素集合看作一种流,流在管道中传输,并且可以在管道的节点上进行筛选,排序,统计,打印,聚合等处理。元素流在管道中经过(操作完后还可以继续其他操作)的处理,最后由(操作完后直接结束,不能调用其他方法)得到前面处理的结果。结合Lambda表达式,简化集合、数组的相关操作。

Lis0bit的博客 480

记:复习java 8 stream 流式写法

今天花了几个小时复习了下 java 8的stream,许久不用,怕忘记,整理下常用知识。 stream 与 lambda 结合真是有如猛虎添翼,大大提升了开发效率,可读性也提高,效率也有提升,所以还是推荐用lambda和stream,真的是优胜于传统for循环太多了。 import java.util.*; import java.util.function.Function; import...

qq_39314099的博客 2397

Java8 Lambda表达式与Stream API (二): Stream API的使用

转载自 本文主要讲解Java8 Stream API,但是要讲解这一部分需要匿名内部类、lambda表达式以及函数式接口的相关知识,本文将分为两篇文章来讲解上述内容,读者可以按需查阅。 Java 匿名内部类、lambda表达式与函数式接口 Java Stream API 本文是本系列文章的第二篇,主要讲解Stream API,在学习Stream API之前要求读者有一定的lambda表达式基础,如果相关知识不了解可以参考本系列文章的第一篇Java 匿名内部类、lambda表达式与函数式接口。 Strea

weixin_46047731的博客 194

java8新特性 lambda表达式、Stream、Optional

Lambda表达式需要函数式接口的支持,格式:()→ {}常见格式格式1:无参无返回值//使用Lambda替代runnable接口中无参无返回的run方法@Testr.run();}格式2:一参无返回值//使用Lambda替代Consumer接口中有一个参数无返回值的accept方法@Test}当然对已一个参数的情况,箭头操作符右边的括号可以省略,等价的代码@Test}格式3:多个参数有返回值//使用Lambda替代比较器接口有两个参数并且返回值的@Test}...

程序员一博 617

lambda表达式Stream流学习一—Lambda与匿名内部类介绍

Lambda与匿名内部类介绍

头好重好重的博客 834

Java 8 Lambda表达式与Stream 流结合使用

使用Lambdas和Streams Stream是对集合的包装,通常和lambda一起使用。 使用lambdas可以支持许多操作,如 map, filter, limit, sorted, count, min, max, sum, collect 等等。 同样,Stream使用懒运算,他们并不会真正地读取所有数据,遇到像getFirst()这样的方法就会结束链式语法。 在接下来的例子中,我们...

weixin_38399962的博客 3152
上一篇: 后端日志【11】:回归自我,负重前行
下一篇: 开发日常小结(39):MYSQL: UNION 和 UNION ALL 的使用与区别
后台技术汇
博客等级 码龄11年 670粉丝 531原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后台技术汇

对你的帮助,是对我的最好鼓励。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值