一、StreamAPI概述
1. Stream与集合的区别
- Stream关注的是对数据的计算,与CPU打交道
- 集合关注的是数据的存储,与内存打交道
2.Stream特征
- Stream 自己不会存储元素
- Stream 不会改变源数据。相反,会返回一个持有结果的新Stream
- Stream 操作是延迟执行的。这意味着会等到需要结果的时候才执行
3.Stream执行流程
- Stream的实例化
- 一系列中间操作(过滤、映射、…)
- 终止操作
4.补充说明
- 一个中间操作链,对数据源的数据进行处理
- 一旦执行终止操作,就执行中间操作链,并产生结果,之后,不会再被使用
二、StreamAPI的使用
1.StreamAPI的实例化方式
/**
* StreamAPI的实例化操作
*/
public class StreamApiCreateTest {
// 创建Stream方式一:通过集合
@Test
public void test1() {
List<User> users = UserData.getUsers();
Stream<User> stream = users.stream(); // 返回一个顺序流
Stream<User> parallelStream = users.parallelStream(); // 返回一个并行流
}
// 创建Stream方式二:通过数组
@Test
public void test2() {
int[] arr = new int[]{1, 2, 3, 4, 5, 6};
IntStream stream = Arrays.stream(arr);
User u1 = new User("张三", 18);
User u2 = new User("李四", 27);
User[] arr1 = new User[]{u1, u2};
Stream<User> userStream = Arrays.stream(arr1);
}
// 创建Stream方式三:通过Stream的of
@Test
public void test3() {
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
}
// 创建Stream方式四:创建无限流
@Test
public void test4() {
// 迭代
Stream.iterate(0, t -> t + 2).limit(10).forEach(System.out::println);
// 生成
Stream.generate(Math::random).limit(10).forEach(System.out::println);
}
}
2.StreamAPI的中间操作
/**
* StreamAPI的中间操作
*/
public class StreamApiMiddleOptTest {
// 一:筛选与切片
@Test
public void test1() {
List<User> list = UserData.getUsers();
Stream<User> stream1 = list.stream();
// filter(p) 查询年龄大于18的用户
stream1.filter(e -> e.getAge() > 18).forEach(System.out::println);
System.out.println("**********************");
// limit(n) 截断流,使其元素不超过数量
Stream<User> stream2 = list.stream();
stream2.limit(3).forEach(System.out::println);
System.out.println("**********************");
// skip(n) 跳过元素,返回一个扔掉了前n个元素的流,若不足n个元素,返回一个空的流
Stream<User> stream3 = list.stream();
stream3.skip(3).forEach(System.out::println);
System.out.println("**********************");
// distinct() 筛选,通过流所生成的元素的hashCode()和equals()去除重复元素
Stream<User> stream4 = list.stream();
stream4.distinct().forEach(System.out::println);
}
// 二:映射
@Test
public void test2() {
// map(f) 接受一个函数作为参数,将元素转换成其他形式或提取信息,该函数会被应用到每个元素上,并将其映射成一个新的元素
List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
list.stream().map(str -> str.toUpperCase()).forEach(System.out::println);
System.out.println("*************************");
// 例子:获取用户姓名长度大于2的用户的姓名
UserData.getUsers().stream()
.filter(u -> u.getName().length() > 2)
.map(u -> u.getName())
.forEach(System.out::println);
System.out.println("*************************");
}
// 三:排序
@Test
public void test3() {
// sorted() 自然排序
List<Integer> list = Arrays.asList(12, 43, 38, 27, 8, 59, 33);
list.stream().sorted().forEach(System.out::println);
System.out.println("****************************");
// sorted(comparator) 定制排序
List<User> users = UserData.getUsers();
users.stream().sorted((u1, u2) -> Integer.compare(u1.getAge(), u2.getAge()))
.forEach(System.out::println);
}
}
3.StreamAPI的终止操作
/**
* StreamAPI的终止操作
*/
public class StreamApiFinalOptTest {
// 一:匹配与查找
@Test
public void test1() {
List<User> users = UserData.getUsers();
// allMatch(predicate) 检查是否匹配所有元素
boolean allMatch = users.stream().allMatch(e -> e.getAge() > 18);
System.out.println(allMatch);
System.out.println("************************");
// anyMatch(predicate) 检查是否至少匹配一个元素
boolean anyMatch = users.stream().anyMatch(e -> e.getAge() > 18);
System.out.println(anyMatch);
System.out.println("************************");
// noneMatch(predicate) 检查是否没有匹配的元素
boolean noneMathch = users.stream().noneMatch(e -> e.getName().startsWith("张"));
System.out.println(noneMathch);
System.out.println("************************");
// findFirst() 找到第一个元素
Optional<User> first = users.stream().findFirst();
System.out.println(first);
System.out.println("************************");
// findAny() 返回当前流中的任意元素
Optional<User> any = users.stream().findAny();
System.out.println(any);
}
@Test
public void test2() {
List<User> users = UserData.getUsers();
// count 返回流中元素的个数
long count = users.stream().count();
System.out.println(count);
System.out.println("************************");
// max(comparator) 返回流中的最大值
Optional<Integer> max = users.stream().map(u -> u.getAge()).max(Integer::compare);
System.out.println(max);
System.out.println("************************");
// min(comparator) 返回流中的最小值
Optional<String> min = users.stream().map(u -> u.getName()).min((s1, s2) -> s1.length() - s2.length());
System.out.println(min);
System.out.println("************************");
// forEach(consumer) 内部迭代
users.stream().forEach(System.out::println);
}
// 二:归约
@Test
public void test3() {
// reduce(T identity, BinaryOperator) 指定初始值,可以将流中的元素反复结合起来,得到一个值
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer sum = list.stream().reduce(0, Integer::sum);
System.out.println(sum);
System.out.println("************************");
// reduce(BinaryOperator) 可以将流中的元素反复结合起来,得到一个值
List<User> users = UserData.getUsers();
Optional<Integer> all = users.stream().map(User::getAge).reduce(Integer::sum);
System.out.println(all);
}
// 三:收集
@Test
public void test4() {
// collect(collector) 将流转换为其他形式。接收一个collector接口的实现
List<User> users = UserData.getUsers();
List<User> collect = users.stream().filter(u -> u.getAge() > 18).collect(Collectors.toList());
collect.stream().forEach(System.out::println);
System.out.println("************************");
Set<User> set = users.stream().filter(u -> u.getAge() > 15).collect(Collectors.toSet());
set.stream().forEach(System.out::println);
}
}
评论区