Java 8 Stream API
内容
- 操作类型:
- 中间操作:对流中的元素进行操作,如过滤(
filter
)、映射(map
)、排序(sorted
)、查找(findFirst
)等。 - 终端操作:结束流操作,并产生结果,如收集(
collect
)、计数(count
)、遍历(forEach
)等。
- 中间操作:对流中的元素进行操作,如过滤(
- 流来源:
- 从集合、数组、I/O资源等创建流。
- 并行处理:
- 支持并行处理,可以高效地处理大数据集。
使用方法
- 创建流:
- 从集合创建流:
List<String> list = Arrays.asList("a", "b", "c"); Stream<String> stream = list.stream();
- 从数组创建流:
int[] numbers = {1, 2, 3}; Stream<Integer> stream = Arrays.stream(numbers);
- 从集合创建流:
- 中间操作:
- 链式调用,如:
stream.filter(s -> s.startsWith("a")).map(String::toUpperCase).forEach(System.out::println);
- 链式调用,如:
- 终端操作:
- 结束流操作,如:
List<String> result = stream.collect(Collectors.toList());
- 结束流操作,如:
Lambda 表达式
内容
- 匿名函数:没有名称的函数,可以传递给方法。
- 单一方法接口:通常用于实现了单一抽象方法的接口。
使用方法
- 创建:
- 定义方法接口的匿名实现,如:
Runnable runnable = () -> System.out.println("Hello, World!");
- 定义带参数的Lambda表达式,如:
Comparator<String> comparator = (s1, s2) -> s1.compareTo(s2);
- 定义方法接口的匿名实现,如:
- 简化代码:
- 代替匿名内部类,如:
list.sort(comparator);
(使用Lambda表达式) - 而不是
list.sort(new Comparator<String>() { ... });
(使用匿名内部类)
- 代替匿名内部类,如:
示例
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 使用Stream API和Lambda表达式
List<String> upperCaseNames = names.stream()
.filter(name -> name.startsWith("A"))
.map(String::toUpperCase)
.collect(Collectors.toList());
upperCaseNames.forEach(System.out::println);
}
}
在这个示例中,使用Stream API和Lambda表达式来处理一个字符串列表,筛选出以"A"开头并转换为大写的字符串,并将结果收集到一个新的列表中。
总结来说,Java 8 Stream API提供了一种新的数据处理方式,而Lambda表达式提供了一种新的代码表达方式。两者结合使用,可以写出更简洁、高效的代码。
中间操作和终端操作
在Java 8的Stream API中,中间操作和终端操作是两个关键概念,它们定义了流处理的不同阶段。
中间操作(Intermediate Operations)
中间操作是流处理的第一阶段。当你对流执行中间操作时,它不会立即执行这些操作,而是会返回一个新的流。这个新的流包含了原始流的所有元素,但会附带额外的信息,用于执行后续操作。
特点:
- 惰性执行:中间操作是惰性的,意味着它们不会立即执行,而是会生成一个新的流。
- 链式调用:你可以将多个中间操作链式调用,形成一个复杂的数据处理流程。
- 返回新的流:每个中间操作都会返回一个新的流。
示例:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream()
.filter(name -> name.startsWith("A"))
.map(String::toUpperCase)
.forEach(System.out::println);
在这个例子中,filter
和map
都是中间操作。它们不会立即执行,而是生成一个新的流,这个流包含了所有以"A"开头并转换为大写的字符串。
终端操作(Terminal Operations)
终端操作是流处理的最终阶段。当你对流执行终端操作时,它会对流中的元素执行最终的计算,并产生一个结果。这个结果可以是任何类型的,比如一个列表、一个计数或者一个计算出的值。
特点:
- 执行并返回结果:终端操作会执行流处理流程,并返回一个结果。
- 结束流处理:一旦终端操作被执行,流处理流程就结束了。
示例:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
int count = names.stream()
.filter(name -> name.startsWith("A"))
.mapToInt(String::length)
.sum();
System.out.println("Number of letters: " + count);
在这个例子中,sum()
是一个终端操作。它对流中的每个元素(这里是字符串的长度)执行求和操作,并返回结果。
总结
- 中间操作:对流进行处理但不立即执行,返回一个新的流。
- 终端操作:对流进行最终的处理并返回结果,结束流处理流程。
理解这两个概念对于正确使用Java 8 Stream API非常重要,因为它们定义了流处理的流程和顺序。