文章目录
在Java 8中引入了流(Stream
)API,它提供了一种新的处理数据的方式,尤其适合于集合操作。流API的设计目的是为了更高效地处理数据集,尤其是当数据集很大时。它支持函数式编程风格,并且可以很容易地并行化。
1.Stream的基本概念
- 源:一个数据源(如集合、数组等)。
- 中间操作:一系列对流进行的操作(如过滤、映射等),这些操作返回一个新的流。
- 终止操作:一个产生结果或者副作用的操作(如收集结果到集合中、打印等),执行完该操作后流被关闭,后续无法再操作。
2.使用Lambda表达式
Lambda 表达式是 Java 8 引入的一个重要特性,它使得代码更加简洁、易于理解和维护。Lambda 表达式允许你把功能作为方法的参数,这极大地简化了函数式接口的使用。
Lambda 表达式的语法
Lambda 表达式的语法非常简单,由三部分组成:
- 参数列表:放在圆括号内,用于声明传入给 lambda 函数的参数。
- 箭头符号:
->
,用于分隔参数列表和要做的动作。 - 函数体:包含了 lambda 表达式所执行的动作。
基本语法格式如下:
(parameters) -> expression
或者带有大括号的格式:
(parameters) -> { statements; }
Lambda 表达式的使用场景
- 事件监听器:在 GUI 编程中,可以使用 lambda 表达式来替代匿名内部类,简化事件监听器的实现。
- 函数式接口:任何具有单一抽象方法的接口都可以与 lambda 表达式一起使用。
- 集合操作:使用
Collections.sort()
或者Stream
API 进行排序或过滤操作。
示例代码
接下来,我们将通过几个具体的示例来展示如何使用 Lambda 表达式。
1. 简单的 Lambda 表达式
// 定义一个接口
interface MathOperation {
int operation(int a, int b);
}
public class LambdaBasics {
public static void main(String[] args) {
MathOperation addition = (a, b) -> a + b;
System.out.println(addition.operation(10, 5)); // 输出 15
// 可以省略类型
MathOperation subtraction = (a, b) -> a - b;
System.out.println(subtraction.operation(10, 5)); // 输出 5
// 如果只有一个参数,则可以省略括号
MathOperation multiply = a -> a * 2;
System.out.println(multiply.operation(10, 0)); // 输出 20
}
}
2. Lambda 表达式与方法引用
public class LambdaBasics {
public static void main(String[] args) {
// 方法引用
MathOperation multiplication = Integer::multiply;
System.out.println(multiplication.operation(10, 5)); // 输出 50
// 构造器引用
Supplier<Person> personSupplier = Person::new;
Person person = personSupplier.get();
person.setName("John Doe");
System.out.println(person.getName()); // 输出 "John Doe"
}
}
class Person {
private String name;
public Person() {}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
3. 使用 Lambda 表达式进行排序
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class LambdaBasics {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
Collections.addAll(fruits, "orange", "apple", "banana");
// 使用 Lambda 表达式排序
Collections.sort(fruits, (s1, s2) -> s1.compareTo(s2));
System.out.println(fruits); // 输出 [apple, banana, orange]
// 使用方法引用排序
Collections.sort(fruits, Comparator.naturalOrder());
System.out.println(fruits); // 输出 [apple, banana, orange]
// 使用 Stream API 和 Lambda 表达式进行排序
List<String> sortedFruits = fruits.stream()
.sorted()
.collect(Collectors.toList());
System.out.println(sortedFruits); // 输出 [apple, banana, orange]
}
}
3.示例代码
下面通过一些具体的例子来说明如何使用Stream API结合Lambda表达式。
(1)创建Stream
- 从集合创建流:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = numbers.stream();
- 从数组创建流:
int[] arr = {1, 2, 3, 4, 5};
IntStream intStream = Arrays.stream(arr);
(2)中间操作
filter
:过滤出符合条件的元素。
stream.filter(n -> n % 2 == 0).forEach(System.out::println); // 输出偶数
map
:对流中的每个元素应用函数。
stream.map(n -> n * n).forEach(System.out::println); // 输出平方数
sorted
:排序。
List<String> names = Arrays.asList("Zoe", "Adam", "Charlie");
names.stream().sorted().forEach(System.out::println); // 按字母顺序排序
distinct
:去除重复项。
List<Integer> numbersWithDuplicates = Arrays.asList(1, 2, 2, 3, 3, 3, 4);
numbersWithDuplicates.stream().distinct().forEach(System.out::println); // 去重
(3)终止操作
collect
:收集流的结果到集合或字符串等。
List<Integer> squaredNumbers = numbers.stream()
.map(n -> n * n)
.collect(Collectors.toList());
System.out.println(squaredNumbers); // [1, 4, 9, 16, 25]
findFirst
:获取第一个元素。
Optional<Integer> first = numbers.stream().findFirst();
first.ifPresent(System.out::println); // 输出第一个元素
count
:计数。
long count = numbers.stream().count();
System.out.println(count); // 输出元素数量
anyMatch
,allMatch
,noneMatch
:检查是否至少有一个、所有或没有元素匹配条件。
boolean hasEven = numbers.stream().anyMatch(n -> n % 2 == 0);
System.out.println(hasEven); // 是否存在偶数
reduce
:聚合元素。
Optional<Integer> sum = Arrays.stream(arr1)
.reduce(Integer::sum);
System.out.println(sum.get());