什么是Stream流?
stream是数据渠道,用于操作数据源(集合、数组)所生产的元素序列。这一类操作称作局和操作,它的基本流程是:
1、将原始数据或数组对象转换为stream流。
2、对stream流中的元素进行一系列的过滤、查找等中间操作(Intermediate Operations),然后 仍返回一个Stream流对象
3、对stream流进行统计、遍历、收集等终结操作(Terminal Operation)获取想要的结果。
Stream流有以下的特点:
stream是不能存储数据,只能对数据进行一些列流式的操作。
stream是惰性加载(延迟执行),一系列流式的操作会在要结果的时候一起执行。
不会修改源数据。
每次操作得到一个新的流,不能对同一个stream执行多次操作 ,因为源流操作过以后就被破坏了。
获取流的三种方式
1、所有的Collection集合都可以使用接口中的默认方法stream()获取Stream流对象。该方法来自StreamSupport类的静态方法。
2、Stream接口的of()静态方法可以获取基本类型和包装类数组、引用类型数组和单个元素的stream对象。of(T… values)方法为可变参数或of(T t)
3、Arrays数组工具类的stream()静态方法可以获取数组元素的stream流对象。
下面是使用Stream的一些常见操作:
- 过滤操作:使用filter()方法根据指定的条件过滤集合中的元素。
- 映射操作:使用map()方法将集合中的元素映射为其他类型的元素。
- 排序操作:使用sorted()方法对集合中的元素进行排序。
- 聚合操作:使用reduce()方法将集合中的元素聚合为一个结果。
- 收集操作:使用collect()方法将Stream的结果收集到一个集合中。
filter
filter用于根据指定的条件筛选出流中符合条件的元素,返回一个新的流。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FilterExample {
public static void main(String[] args) {
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。我们使用numbers.stream()
将List转换为一个Stream对象。然后,我们使用filter()
方法传入一个lambda表达式n -> n % 2 == 0
,该表达式指定我们只保留能被2整除的元素(即偶数)。最后,我们使用collect(Collectors.toList())
将过滤后的结果收集到一个新的List中。
运行上述代码,输出将是过滤后的偶数列表:[2, 4, 6, 8, 10]。
map
map用于对流中的每个元素执行一个函数,并将函数的结果映射为一个新的元素。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> upperCaseNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(upperCaseNames); // 输出:[ALICE, BOB, CHARLIE, DAVID]
}
}
在这个例子中,我们有一个包含了一些字符串的List。我们使用names.stream()
将List转换为一个Stream对象。然后,我们使用map()
方法传入一个方法引用String::toUpperCase
,该方法引用将每个字符串转换为大写形式。最后,我们使用collect(Collectors.toList())
将转换后的结果收集到一个新的List中。
运行上述代码,输出将是转换后的大写字符串列表:[ALICE, BOB, CHARLIE, DAVID]。
sotred
sotred用于对流中的元素进行排序。它可以对流中的元素按照自然顺序或者自定义的排序规则进行排序操作。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class SortedExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 9, 3);
List<Integer> sortedNumbers = numbers.stream()
.sorted()
.collect(Collectors.toList());
System.out.println(sortedNumbers); // 输出:[1, 2, 3, 5, 8, 9]
}
}
在这个例子中,我们有一个包含了一些整数的List。我们使用numbers.stream()
将List转换为一个Stream对象。然后,使用sorted()
方法对整数进行升序排列。最后,我们使用collect(Collectors.toList())
将排好序的结果收集到一个新的List中。
运行上述代码,输出将是升序排列后的整数列表:[1, 2, 3, 5, 8, 9]。
reduce
reduce用于将流中的元素进行合并或归约。它可以把一个流缩减为单个值,或者将流中的元素组合为一个新的对象。
import java.util.Arrays;
import java.util.List;
public class ReduceExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
System.out.println("Sum: " + sum); // 输出:Sum: 15
}
}
在上述示例中,我们有一个包含了一些整数的List。我们使用numbers.stream()
将List转换为一个Stream对象。然后,我们使用reduce
操作传入初始值0和一个lambda表达式(a, b) -> a + b
,该lambda表达式指定将两个元素相加的逻辑。最后,我们得到了所有元素的求和结果。
运行上述代码,输出将是整数流的求和结果:Sum: 15。
collect
collect用于将流中的元素收集到一个集合或数据结构中。它可以收集流中的元素,然后生成一个List、Set、Map或其他自定义集合。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class CollectExample {
public static void main(String[] args) {
List<String> fruits = Arrays.asList("apple", "banana", "orange", "grape");
List<String> collectedFruits = fruits.stream()
.collect(Collectors.toList());
System.out.println(collectedFruits); // 输出:[apple, banana, orange, grape]
}
}
在上述示例中,我们有一个包含了一些水果的List。我们使用fruits.stream()
将List转换为一个Stream对象。然后,我们使用collect()
操作,并传入Collectors.toList()
作为参数,该方法指定将元素收集为一个List。最后,我们得到了一个包含了所有水果的List对象。
运行上述代码,输出将是收集到的水果列表:[apple, banana, orange, grape]。