目录
什么是Stream流?
Stream流是Java 8中新增的一种处理集合数据的方式,它提供了一种类似于数据库操作的流式处理方式,可以对集合进行过滤、映射、排序、聚合等操作,使得集合操作更加简洁、高效。
Stream流主要有以下几个特点:
- Stream流不是数据结构,不会改变源数据,而是通过对源数据的操作来产生新的数据流。
- Stream流支持链式操作,可以进行多个操作的组合,使得代码更加简洁。
- Stream流支持延迟操作,只有在终止操作时才会进行计算,可以提高程序的性能。
- Stream流可以进行并行操作,利用多核处理器的性能优势,提高程序的计算速度。
如何使用Stream流?
使用Stream流可以分为以下几个步骤:
- 获取数据源:可以通过集合、数组、IO流等方式获取数据源。
- 转换为流:通过stream()、parallelStream()等方法将数据源转换为流。
- 中间操作:对流进行中间操作,如过滤、映射、排序、去重等操作,这些操作会返回一个新的流。
- 终止操作:对流进行终止操作,如收集、计数、查找、匹配等操作,这些操作会返回一个结果。
下面将分别介绍各个操作的方法和使用示例。
1.获取数据源
可以通过集合、数组、IO流等方式获取数据源。
使用集合获取数据源
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
使用数组获取数据源
String[] array = {
"apple", "banana", "orange", "grape", "watermelon"};
2.转换为流
通过stream()、parallelStream()等方法将数据源转换为流。
将集合转换为流
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
Stream<String> stream = list.stream();
将数组转换为流
String[] array = {
"apple", "banana", "orange", "grape", "watermelon"};
Stream<String> stream = Arrays.stream(array);
3.中间操作
对流进行中间操作,如过滤、映射、排序、去重等操作,这些操作会返回一个新的流。
过滤数据
过滤掉长度小于等于5的字符串:
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
Stream<String> stream = list.stream().filter(str -> str.length() > 5);
映射数据
提取出所有水果的名称:
List<Fruit> fruits = Arrays.asList(
new Fruit("apple", "red"),
new Fruit("banana", "yellow"),
new Fruit("orange", "orange"),
new Fruit("grape", "purple"),
new Fruit("watermelon", "green")
);
Stream<String> stream = fruits.stream().map(Fruit::getName);
排序数据
按照水果名称进行排序:
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
Stream<String> stream = list.stream().sorted();
去重数据
去掉重复的水果名称:
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon", "apple", "banana");
Stream<String> stream = list.stream().distinct();
4.终止操作
对流进行终止操作,如收集、计数、查找、匹配等操作,这些操作会返回一个结果。
收集数据
将水果名称收集到一个列表中:
List<Fruit> fruits = Arrays.asList(
new Fruit("apple", "red"),
new Fruit("banana", "yellow"),
new Fruit("orange", "orange"),
new Fruit("grape", "purple"),
new Fruit("watermelon", "green")
);
List<String> names = fruits.stream().map(Fruit::getName).collect(Collectors.toList());
计数数据
统计水果名称的数量:
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon", "apple", "banana");
long count = list.stream().count();
查找数据
查找第一个水果名称:
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
Optional<String> first = list.stream().findFirst();
匹配数据
判断是否包含某个水果名称:
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
boolean contains = list.stream().anyMatch(str -> str.equals("banana"));
如何使用Lambda表达式?
Lambda表达式可以在函数接口中使用,函数接口是指只包含一个抽象方法的接口。
Lambda表达式的基本语法:
(parameters) -> expression
其中,parameters为方法的参数列表,expression为方法体。
下面将分别介绍Lambda表达式的使用示例。
1.使用Lambda表达式作为参数
将Lambda表达式作为参数传递给另一个方法:
public void process(int num, IntConsumer consumer) {
consumer.accept(num);
}
public static void main(String[] args) {
LambdaExample example = new LambdaExample();
// 使用Lambda表达式作为参数
example.process(10, (num) -> System.out.println(num));
// 使用Lambda表达式实现函数接口
Function<Integer, Integer> square = (num) -> num * num;
int result = square.apply(5);
System.out.println(result);
// 使用Lambda表达式简化集合操作
List<String> list = Arrays.asList("apple", "banana", "orange", "grape", "watermelon");
// 使用Lambda表达式实现筛选
List<String> filteredList = list.stream().filter(str -> str.length() > 5).collect(Collectors.toList());
// 使用Lambda表达式实现映射
List<String> mappedList = list.stream().map(str -> str.toUpperCase()).collect(Collectors.toList());
// 使用Lambda表达式实现排序
List<String> sortedList = list.stream().sorted().collect(Collectors.toList());
// 使用Lambda表达式实现去重
List<String> distinctList = list.stream().distinct().collect(Collectors.toList());
}
2.使用Lambda表达式实现函数接口
使用Lambda表达式实现一个函数接口:
Function<Integer, Integer> square = (num) -> num * num;
3.使用Lambda表达式简化集合操作
Lambda表达式可以简化集合操作,如筛选、映射、排序、去重等操作。下面是一些常见的集合操作示例:
3.1 筛选操作
筛选操作可以通过filter方法实现,它可以根据条件筛选集合中的元素,并返回一个新的Stream流。例如,下面是一个筛选操作的示例:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println(evenNumbers); // [2, 4, 6, 8, 10]
该示例中,首先创建一个包含整数1到10的List集合,然后使用Stream流的filter方法筛选出其中的偶数,并将结果保存到一个新的List集合中。
3.2 映射操作
映射操作可以通过map方法实现,它可以将集合中的元素映射为另一个元素,并返回一个新的Stream流。例如,下面是一个映射操作的示例:
List<String> words = Arrays.asList("hello", "world", "java", "stream", "lambda");
List<Integer> lengths = words.stream()
.map(String::length)
.collect(Collectors.toList());
System.out.println(lengths); // [5, 5, 4, 6, 6]
该示例中,首先创建一个包含字符串的List集合,然后使用Stream流的map方法将每个字符串映射为它的长度,并将结果保存到一个新的List集合中。
3.3 排序操作
排序操作可以通过sorted方法实现,它可以对集合中的元素进行排序,并返回一个新的Stream流。例如,下面是一个排序操作的示例:
List<String> words = Arrays.asList("hello", "world", "java", "stream", "lambda");
List<String> sortedWords = words.stream()
.sorted()
.collect(Collectors.toList());
System.out.println(sortedWords); // [hello, java, lambda, stream, world]
该示例中,首先创建一个包含字符串的List集合,然后使用Stream流的sorted方法对字符串进行排序,并将结果保存到一个新的List集合中。
3.4 去重操作
去重操作可以通过distinct方法实现,它可以将集合中重复的元素去除,并返回一个新的Stream流。例如,下面是一个去重操作的示例:
List<Integer> numbers = Arrays.asList(1, 2, 3, 2, 4, 5, 4, 6, 7, 5);
List<Integer> distinctNumbers = numbers.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(distinctNumbers); // [1, 2, 3, 4
Lambda表达式的使用场景
Lambda表达式适合处理以下场景:
- 函数式接口:Lambda表达式可以作为函数式接口的实现。函数式接口只包含一个抽象方法的接口,可以使用Lambda表达式来实现该方法。
- 集合操作:Stream流可以用于处理集合中的元素,如筛选、映射、排序、去重等操作,可以使用Lambda表达式来简化代码。
- 多线程编程:Lambda表达式可以作为Runnable和Callable接口的实现,可以更方便地实现多线程编程。
- GUI事件监听器:Lambda表达式可以用于处理GUI事件监听器中的事件处理方法,可以使得代码更加简洁。
Stream流和Lambda表达式的优点
使用Stream流和Lambda表达式有以下优点:
- 简洁:使用Stream流和Lambda表达式可以使代码更加简洁、可读,降低代码的复杂度。
- 易于维护:使用Stream流和Lambda表达式可以使代码更加易于维护,减少代码的重复性。
- 并发执行:Stream流可以支持并发执行,提高程序的执行效率。
- 高效:使用Stream流和Lambda表达式可以使代码更加高效,减少内存和CPU的开销。
结论
Stream流和Lambda表达式是Java 8中的两个重要特性,它们可以使得代码更加简洁、可读、灵活,同时可以提高代码的效率和可维护性。如果您还没有使用过Stream流和Lambda表达式,那么希望这篇教程能够帮助您入门。