【Java入门指南 Day11:Lambda表达式与Stream API】

devtools/2024/12/24 0:33:55/

一、Lambda表达式基础

Lambda表达式是Java 8引入的一个重要特性,它让我们可以将行为像数据一样传递。可以把它理解为一种简洁的、匿名的函数定义方式。

Lambda表达式语法

java">// 基本语法: (参数) -> {表达式}// 1. 无参数
Runnable r = () -> System.out.println("Hello");// 2. 单个参数(可以省略括号)
Consumer<String> consumer = str -> System.out.println(str);// 3. 多个参数
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;// 4. 带代码块
Comparator<String> c = (s1, s2) -> {System.out.println("Comparing");return s1.compareTo(s2);
};

Lambda表达式的类型推断

java">// Java编译器可以根据上下文推断Lambda表达式的参数类型
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");// 不需要指定String类型
names.sort((x, y) -> x.compareToIgnoreCase(y));

二、函数式接口

函数式接口是只有一个抽象方法的接口,可以用@FunctionalInterface注解标记。

常用函数式接口

java">// 1. Consumer:接收一个参数,不返回结果
Consumer<String> printer = s -> System.out.println(s);// 2. Function:接收一个参数,返回一个结果
Function<String, Integer> lengthFunc = s -> s.length();// 3. Predicate:接收一个参数,返回布尔值
Predicate<String> isEmpty = s -> s.isEmpty();// 4. Supplier:不接收参数,返回一个结果
Supplier<Double> random = () -> Math.random();

自定义函数式接口

java">@FunctionalInterface
interface MathOperation {int operate(int a, int b);// 可以有默认方法default int operateDouble(int a, int b) {return operate(a, b) * 2;}
}// 使用自定义函数式接口
MathOperation add = (a, b) -> a + b;
MathOperation multiply = (a, b) -> a * b;

三、Stream API详解

Stream API提供了一种声明式的方式来处理数据集合。

Stream操作基础

java">List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");// 创建流
Stream<String> stream = names.stream();// 链式操作
List<String> filteredNames = names.stream().filter(name -> name.length() > 4)    // 过滤.map(String::toUpperCase)             // 转换.sorted()                             // 排序.collect(Collectors.toList());        // 收集结果

常用Stream操作

java">List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);// 1. 筛选和切片
List<Integer> evenNumbers = numbers.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());// 2. 映射
List<String> numberStrings = numbers.stream().map(String::valueOf).collect(Collectors.toList());// 3. 归约
int sum = numbers.stream().reduce(0, Integer::sum);// 4. 收集
Map<Boolean, List<Integer>> evenOddMap = numbers.stream().collect(Collectors.groupingBy(n -> n % 2 == 0));

四、并行流和性能优化

并行流使用

java">// 将顺序流转换为并行流
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.parallelStream().mapToInt(Integer::intValue).sum();// 复杂操作的并行处理
List<String> processedData = bigList.parallelStream().filter(item -> item != null).map(item -> processItem(item)).collect(Collectors.toList());

性能优化建议

java">// 1. 避免在并行流中使用有状态操作
// 不好的例子
AtomicInteger counter = new AtomicInteger();
stream.parallel().forEach(item -> counter.incrementAndGet());// 2. 使用适当的数据结构
// 好的例子
ArrayList<Integer> list = new ArrayList<>();
// 不好的例子
LinkedList<Integer> linkedList = new LinkedList<>();

五、Optional类使用

Optional类是用来防止空指针异常的容器对象。

java">// 创建Optional对象
Optional<String> optional = Optional.of("Hello");
Optional<String> empty = Optional.empty();
Optional<String> nullable = Optional.ofNullable(null);// 安全地获取值
String result = optional.orElse("Default");
String result2 = optional.orElseGet(() -> "Computed Default");
String result3 = optional.orElseThrow(() -> new RuntimeException("Value not present"));// 链式操作
Optional<String> name = Optional.ofNullable(user).map(User::getAddress).map(Address::getCity).map(City::getName);

最佳实践建议 💡

  1. Lambda表达式
    • 保持简短和清晰
    • 避免在Lambda中使用复杂的逻辑
    • 适当使用方法引用
  2. Stream操作
    • 使用合适的终端操作
    • 注意流操作的顺序
    • 避免过度使用Stream
  3. 并行流
    • 在适当的场景使用并行流
    • 注意数据量和计算复杂度
    • 考虑线程安全性

常见陷阱提醒 ⚠️

  1. Lambda陷阱
java">// 错误:在Lambda中修改外部变量
int sum = 0;
list.forEach(i -> sum += i);  // 编译错误
  1. Stream陷阱
java">// 错误:重复使用Stream
Stream<String> stream = list.stream();
stream.forEach(System.out::println);
stream.forEach(System.out::println);  // IllegalStateException
  1. Optional陷阱
java">// 错误:不恰当的Optional使用
Optional<String> optional = Optional.ofNullable(str);
if (optional.isPresent()) {  // 不推荐return optional.get();
} else {return "default";
}// 正确方式
return optional.orElse("default");

函数式编程特性大大提升了Java的表达能力和代码简洁性。合理使用这些特性可以写出更加优雅和高效的代码。


http://www.ppmy.cn/devtools/144846.html

相关文章

微服务核心概念介绍

微服务架构的核心概念包括&#xff1a; 1. 服务拆分与粒度&#xff1a;将应用程序按照业务领域或功能边界拆分为多个粒度适中的服务&#xff0c;每个服务都负责完成一项具体的业务功能或流程。 2. 自治性&#xff1a;每个微服务都是自治的&#xff0c;意味着它们可以独立地进行…

RK3568平台(KBuild篇)KBuild编译体系

一.KBuild体系简介 从Linux内核2.6开始,Linux内核的编译采用Kbuild系统,这和过去的编译系统有很大的不同,尤其对于Linux内核模块的编译。在新的系统下,Linux编译系统会两次扫描Linux的Makefile:首先编译系统会读取Linux内核顶层的Makefile,然后根据读到的内容第二次读取…

机器学习之拟合

在机器学习中&#xff0c;拟合&#xff08;Fitting&#xff09; 是指通过训练数据来调整模型参数&#xff0c;使得模型能够较好地预测输出或逼近真实数据的分布。拟合程度决定了模型的表现&#xff0c;主要分为三种情况&#xff1a;欠拟合&#xff08;Underfitting&#xff09;…

配置flutter 解决andriod studio报错 no device selected

flutter配置好后 明明下载好了模拟器 但是在andriod studio 找不到设备 显示no devices 这个时候需要我们配置一下flutter关联的android sdk的路径和文件夹 就可以解决了 flutter config --android-sdk 自己android studio的路径 这样配置就可以解决了~

Unity-Editor扩展GUI基本实现一个可拖拉放的格子列表

短短几百行代码,好吧,又是“参考”了国外的月亮 操作,还真地挺自然的。。。。。。国外的实现有点小牛 拖拉,增加+ 一个Element 鼠标左键长按,可以出提示 鼠标右键,清除Element, 有点小bug,不是很自然地完全清除, using System.Collections; using System.Collecti…

【EXCEL 逻辑函数】AND、OR、XOR、NOT、IF、IFS、IFERROR、IFNA、SWITCH

目录 AND&#xff1a;当所有条件都为真时返回 TRUE&#xff0c;否则返回 FALSE OR&#xff1a;当任一条件为真时返回 TRUE&#xff0c;否则返回 FALSE XOR&#xff1a;当奇数个条件为真时返回 TRUE&#xff0c;否则返回 FALSE NOT &#xff1a;反转逻辑值 IF&#xff1a;根…

使用一个线性电位器将运算放大器增益从 -30 dB 调整到 +60 dB

良好的手动调节音频增益级具有以下特点&#xff1a; 低噪声、低失真&#xff0c; 20 kHz 带宽&#xff0c; 宽增益调节范围&#xff08;例如90dB&#xff09;&#xff0c;以及 对数&#xff08;至少伪对数&#xff09;控制特性 有效地跨越宽增益范围和良好的分辨率&#x…

吉快科技荣膺“金边奖·最佳大模型一体机”,引领AI边缘新时代

2024年12月14日&#xff0c;由边缘计算社区主办的全球边缘计算大会在上海盛大召开。这场备受瞩目的行业盛会汇聚了全球顶尖的技术专家、企业代表与行业领袖&#xff0c;共同探讨边缘计算与AI技术融合的最新趋势。在本次大会的重磅环节——“金边奖”颁奖典礼上&#xff0c;吉快…