07 Lambda和StreamAPI

目录

1.Lambda表达式

语法格式:

简单示例

2.函数式接口

常见的函数式接口

1. Supplier

2. Consumer

3. Function,>

4. Predicate

总结

3.流式编程——StreamAPI

基本概念

常见的 Stream 操作

1. 创建 Stream

2. 中间操作

3. 终端操作

简单练习


1.Lambda表达式

java的核心编程思想——面向对象:强调的是对象,有什么属性,什么能力等等。

函数式编程思想——强调结果:不关心过程,对应的代表就是Lambda表达式。

Lambda表达式是一种匿名函数,可以在代码中用于创建简洁的内联函数。它们通常用于需要简单功能的地方,尤其是在使用函数作为参数的情况下,如排序、过滤或映射操作。

语法格式:
(parameters) -> expression

或者是

(parameters) -> { statements; }
简单示例

假设我们有一个列表,想通过lambda表达式来过滤出偶数:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
​
public class LambdaExample {public static void main(String[] args) {List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);List<Integer> evenNumbers = numbers.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());System.out.println(evenNumbers);  // 输出 [2, 4, 6]}
}

2.函数式接口

Lambda表达式是有适用前提的:

1.必须是函数式接口做方法参数传递 2.函数式接口:有且只有一个抽象方法的接口,用@FunctionalInterface去检测

常见的函数式接口

SupplierConsumerFunctionPredicate 是最常用的几个。这些接口(40多个)位于 java.util.function 包下,主要用于支持Lambda表达式和方法引用,使得代码更简洁、更具有表现力。

1. Supplier<T>

Supplier 接口表示一个无参且有返回值的函数。它的方法 get() 返回一个结果。

接口定义:

@FunctionalInterface
public interface Supplier<T> {T get();
}

示例

Supplier<String> supplier = () -> "Hello, World!";
String result = supplier.get();
System.out.println(result);  // 输出 Hello, World!
2. Consumer<T>

Consumer 接口表示一个接受单个输入参数并且没有返回值的函数。它的方法 accept(T t) 处理传入的参数。

接口定义:

@FunctionalInterface
public interface Consumer<T> {void accept(T t);
}

示例:

Consumer<String> consumer = System.out::println;
consumer.accept("Hello, World!");  // 输出 Hello, World!
3. Function<T, R>

Function 接口表示一个接受一个参数并产生一个结果的函数。它的方法 apply(T t) 将输入参数转换为输出结果。

接口定义:

@FunctionalInterface
public interface Function<T, R> {R apply(T t);
}

示例:

Function<String, Integer> function = String::length;
int length = function.apply("Hello, World!");
System.out.println(length);  // 输出 13
4. Predicate<T>

Predicate 接口表示一个接受一个参数并返回一个布尔值的函数。它的方法 test(T t) 检查某个条件是否满足。

接口定义:

@FunctionalInterface
public interface Predicate<T> {boolean test(T t);
}

示例:

Predicate<String> predicate = s -> s.length() > 5;
boolean isLong = predicate.test("Hello, World!");
System.out.println(isLong);  // 输出 true
总结
  • Supplier< T >: 无参,有返回值。

  • Consumer<T>: 有参,无返回值。

  • Function<T, R>: 有参,有返回值。

  • Predicate<T>: 有参,返回布尔值。

3.流式编程——StreamAPI

Stream API 提供了一种声明式的方式对数据进行操作,支持函数式编程风格,使代码更加简洁、易读和高效,是一个强大的工具,用于处理集合数据。

基本概念
  1. Stream: 数据的序列,支持连续的、基于某种规则的操作。

  2. Pipeline: 流水线,由源(数据源)、中间操作(Intermediate Operations)和终端操作(Terminal Operations)组成。

  3. 懒求值: 中间操作不会立即执行,而是在终端操作触发时才会执行。

常见的 Stream 操作
1. 创建 Stream
  • 从集合创建:

    List<String> list = Arrays.asList("apple", "banana", "cherry");
    Stream<String> stream = list.stream();
  • 从数组创建:

    String[] array = {"apple", "banana", "cherry"};
    Stream<String> stream = Arrays.stream(array);
  • 从文件创建:

    try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {lines.forEach(System.out::println);
    } catch (IOException e) {e.printStackTrace();
    }
2. 中间操作
  • filter: 过滤流中的元素。

    List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");
    List<String> filteredFruits = fruits.stream().filter(fruit -> fruit.startsWith("a")).collect(Collectors.toList());
  • map: 转换流中的元素。

    List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");
    List<Integer> lengths = fruits.stream().map(String::length).collect(Collectors.toList());
  • flatMap: 将流中的每个元素转换为一个新的流,然后将所有这些流合并成一个流。

    List<List<Integer>> lists = Arrays.asList(Arrays.asList(1, 2),Arrays.asList(3, 4)
    );
    List<Integer> flatList = lists.stream().flatMap(List::stream).collect(Collectors.toList());
  • distinct: 去重。

    List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
    List<Integer> distinctNumbers = numbers.stream().distinct().collect(Collectors.toList());
  • sorted: 排序。

    List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6);
    List<Integer> sortedNumbers = numbers.stream().sorted().collect(Collectors.toList());
3. 终端操作
  • forEach: 遍历流中的每个元素。

    List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");
    fruits.stream().forEach(System.out::println);
  • collect: 将流中的元素收集到一个集合中。

    List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");
    List<String> collectedFruits = fruits.stream().filter(fruit -> fruit.startsWith("a")).collect(Collectors.toList());
  • reduce: 对流中的元素进行累积操作。

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    int sum = numbers.stream().reduce(0, Integer::sum);
  • anyMatch: 检查流中是否有任何元素匹配给定的条件。

    List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");
    boolean hasApple = fruits.stream().anyMatch(fruit -> fruit.equals("apple"));
  • allMatch: 检查流中的所有元素是否都匹配给定的条件。

    List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");
    boolean allStartWithA = fruits.stream().allMatch(fruit -> fruit.startsWith("a"));
  • noneMatch: 检查流中没有任何元素匹配给定的条件。

    List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");
    boolean noneStartWithZ = fruits.stream().noneMatch(fruit -> fruit.startsWith("z"));
  • findFirst: 返回流中的第一个元素。

    List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");
    Optional<String> firstFruit = fruits.stream().findFirst();
  • count: 计算流中的元素数量。

    List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");
    long count = fruits.stream().count();
简单练习

1.数据准备:数组存放人物对象,包含名字和年龄,使用《剑来》里的人物。

2.操作练习:

分别进行如下操作:

  • 获取男性队伍并打印。

  • 获取女性队伍并打印。

  • 男性队伍按年龄倒序排序,取前3。确保结果包含"陈平安"。

  • 女性队伍按年龄倒序排序,去掉前2。确保结果包含"宁姚"。

  • 合并两个队伍,并打印。

Person定义:

public class Person {private String name;private int age;private String gender;
​public Person(String name, int age, String gender) {this.name = name;this.age = age;this.gender = gender;}
​public String getName() {return name;}
​public int getAge() {return age;}
​public String getGender() {return gender;}
​@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + ", gender='" + gender + "'}";}
}

StreamAPITest:

public class StreamAPITest {public static void main(String[] args) {List<Person> people = Arrays.asList(new Person("陈平安", 20, "男"),new Person("宁姚", 18, "女"),new Person("崔东山", 22, "男"),new Person("李宝瓶", 16, "女"),new Person("裴钱", 15, "女"),new Person("朱河", 25, "男"),new Person("陈灵均", 21, "男"),new Person("陈如初", 17, "女"),new Person("周米粒", 14, "女"),new Person("李二", 33, "男"),new Person("郑大风", 35, "男"));
​// 1. 获取男性队伍并打印List<Person> maleTeam = people.stream().filter(person -> person.getGender().equals("男")).collect(Collectors.toList());System.out.println("男性队伍:");maleTeam.forEach(System.out::println);
​// 2. 获取女性队伍并打印List<Person> femaleTeam = people.stream().filter(person -> person.getGender().equals("女")).collect(Collectors.toList());System.out.println("女性队伍:");femaleTeam.forEach(System.out::println);
​// 3. 男性队伍按年龄排序,取前三,确保包含陈平安List<Person> topThreeMales = maleTeam.stream().sorted(Comparator.comparingInt(Person::getAge).reversed()).limit(3).collect(Collectors.toList());
​while (!topThreeMales.stream().anyMatch(p -> p.getName().equals("陈平安"))) {topThreeMales = maleTeam.stream().sorted(Comparator.comparingInt(Person::getAge).reversed()).limit(topThreeMales.size() + 1).collect(Collectors.toList());}
​System.out.println("男性队伍按年龄排序,取前三:");topThreeMales.forEach(System.out::println);
​// 4. 女性队伍按年龄排序,去掉前2,确保包含宁姚List<Person> remainingFemales = femaleTeam.stream().sorted(Comparator.comparingInt(Person::getAge).reversed()).skip(2).collect(Collectors.toList());
​while (!remainingFemales.stream().anyMatch(p -> p.getName().equals("宁姚"))) {remainingFemales = femaleTeam.stream().sorted(Comparator.comparingInt(Person::getAge).reversed()).skip(femaleTeam.size() - remainingFemales.size() - 1).collect(Collectors.toList());}
​System.out.println("女性队伍按年龄排序,去掉前2:");remainingFemales.forEach(System.out::println);
​// 5. 合并两个队伍,并打印List<Person> combinedTeam = Stream.concat(topThreeMales.stream(), remainingFemales.stream()).collect(Collectors.toList());System.out.println("合并后的队伍:");combinedTeam.forEach(System.out::println);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/8878.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

TMDOG的Gin学习笔记_02——Gin集成支付宝支付沙箱环境

TMDOG的Gin学习笔记_02——Gin集成支付宝支付沙箱环境 博客地址&#xff1a;TMDOG的博客 作者自述&#xff1a; 最近忙着整理自己的项目代码&#xff0c;终于有时间更新一下博客。这次的内容是关于如何在Gin框架下集成支付宝的支付沙箱环境&#xff0c;具体包括如何初始化支付…

Docker网络概述

1. Docker 网络概述 1.1 网络组件 Docker网络的核心组件包括网络驱动程序、网络、容器以及IP地址管理&#xff08;IPAM&#xff09;。这些组件共同工作&#xff0c;为容器提供网络连接和通信能力。 网络驱动程序&#xff1a;Docker支持多种网络驱动程序&#xff0c;每种驱动程…

OpenHarmony4.1蓝牙芯片如何适配?触觉智能RK3568主板SBC3568演示

当打开蓝牙后没有反应时&#xff0c;需要排查蓝牙节点是否对应、固件是否加载成功&#xff0c;本文介绍开源鸿蒙OpenHarmony4.1系统下适配蓝牙的方法&#xff0c;触觉智能SBC3568主板演示 修改对应节点 开发板蓝牙硬件连接为UART1&#xff0c;修改对应的节点&#xff0c;路径为…

QT 如何使QLabel的文字垂直显示

想要实现QLabel文字的垂直显示&#xff0c;可以通过使用“文字分割填充换行符”的方式来实现QLabel文字垂直显示的效果&#xff0c;下面是效果图&#xff1a; 具体实现代码&#xff1a; #include "mainwindow.h" #include "ui_mainwindow.h"MainWindow:…

数据结构选择题及答案

一、选择题 1、下列查找方法中&#xff0c;&#xff08; &#xff09;适用于查找有序单链表。 A&#xff0e;分块查找; B&#xff0e;哈希查找; C&#xff0e;顺序查找; D&#xff0e;二分查找; 2、在有n个结点的二叉树的二叉链表表示中&#xff0c;空指针数为( )。 A&#xf…

2024上半年上午30

CPU没有减法器的说法

php实现excel表格数据快速入库

项目场景&#xff1a;大概有一百来份excel表格数据需要整理入库&#xff0c;基础字段一样&#xff0c;如果按照传统的处理方法&#xff0c;需要先整理好数据&#xff08;数据清洗、合并等&#xff09;&#xff0c;并且按照系统导入模板整理出来&#xff0c;费时费力。 需要解决…

【青牛科技】GC5931:工业风扇驱动芯片的卓越替代者

在工业领域&#xff0c;工业风扇的稳定高效运行对于维持良好的生产环境至关重要。而驱动芯片作为工业风扇控制系统的核心元件&#xff0c;其性能直接影响风扇的工作状态。芯麦 GC5931 作为一款新型驱动芯片&#xff0c;在替代 A5931/Allegro 应用于工业风扇中展现出了非凡的优势…

CST案例分析:TLM算法仿真5G毫米波手机天线和整机

5G时代&#xff0c;产品复杂&#xff0c;更新换代快&#xff0c;如何快速仿真不同的设计版本是影响研发效率的关键问题。本期我们用达索系统SIMULIA自己的手机模型来演示5G毫米波的仿真。 &#xff08;图片仅为概念演示&#xff0c;未经达索系统授权不得使用&#xff09; 完整的…

小猿口算炸鱼脚本

目录 写在前面&#xff1a; 一、关于小猿口算&#xff1a; 二、代码逻辑 1.数字识别 2.答题部分 三、代码分享&#xff1a; 补充&#xff1a;软件包下载 写在前面&#xff1a; 最近小猿口算已经被不少大学生攻占&#xff0c;小学生直呼有挂。原本是以为大学生都打着本…

【debug】QT 相关问题error汇总

总结一下碰到过的所有问题error以及解决方案 qt的UI更新之后构建后发现没有变化 取消项目中的Shadow build的勾选&#xff0c;作用是取消影子构建&#xff0c;此后构建目录与源码处于同一目录&#xff0c;每次编译更新程序使用的UI文件error: ‘class QWidget’ has no member…

滑动窗口最大值

239. 滑动窗口最大值 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 …

GEE 案例——利用哨兵-2 图像时间序列和谷歌地球引擎云计算自动绘制和监测香港海洋水质参数

目录 简介 结论 代码 结果 APP链接 引用 简介 对沿海水质的持续监测对于水资源管理和海洋生态系统的可持续性至关重要。 遥感数据&#xff08;如哨兵-2 卫星图像&#xff09;可提供用于时间序列分析的高分辨率观测数据&#xff0c;而基于云的谷歌地球引擎&#xff08;GE…

Redis4:Redis的Java客户端

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

基于Java Web的传智播客crm企业管理系统的设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

【Eclipse系列】eclipse安装与常规配置(含插件)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、下载与安装 二、常规设置 1.1.设置工作空间(workspace) 1.2.设置字体和字体大小 ​编辑 1.3.设置编码 1.4.去除验证(validation) 1.5.去除单词验证(spelli…

抗辐照MCU芯片工艺解析:如何保障芯片的可靠性

行星探索、轨道飞行器任务和空间研究在内的太空项目需要创新的航天器系统技术提供通信与处理功能。随着商业航天的发展&#xff0c;对于航天电子系统需要考虑高可靠与高性能的同时&#xff0c;还需要考虑降低开发成本和缩短上市时间。 以MCU芯片AS32A401为例&#xff0c;该芯片…

qt QKeySequence详解

1、概述 QKeySequence 是 Qt 框架中的一个类&#xff0c;用于表示和处理键盘快捷键序列。它提供了一种方便的方式来解析、存储和比较键盘快捷键&#xff0c;这些快捷键通常用于触发应用程序中的特定操作或命令。QKeySequence 支持多种格式的快捷键表示&#xff0c;包括单个按键…

【RMA】基于知识注入和模糊学习的多模态歧义分析

abstract 多模态情感分析&#xff08;MSA&#xff09;利用互补的多模态特征来预测情感极性&#xff0c;主要涉及语言、视觉和音频三种模态。现有的多模态融合方法主要考虑不同模态的互补性&#xff0c;而忽略了模态之间的冲突所导致的歧义&#xff08;即文本模态预测积极情绪&…

移动取证和 Android 安全

当今的数字时代已经产生了许多技术进步&#xff0c;无论是智能手机还是虚拟现实、人工智能和物联网 (IoT) 等下一代基础技术。 智能手机已不再只是奢侈品&#xff0c;而是我们生存所必需的东西。根据各种统计数据&#xff0c;如今全球有超过 50% 的人使用手机。 由于数据存储…