Java8中有两大最为重要的改变。第一个是 Lambda 表达式;另外一 个则是 Stream API(java.util.stream.*)。 Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对 集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数 据库查询。也可以使用 Stream API 来并行执行操作。简而言之, Stream API 提供了一种高效且易于使用的处理数据的方式。 JDK8第二大特性 Stream流 Stream流: 是一个数据渠道 用于操作数据源所生成的元素序列 注意:Stream 流 不存储数据 不会改变源数据 返回一个持有结果的新的Stream Stream操作是延迟执行的 如果不执行收尾操作 中间操作不会执行 Stream 流操作的三个步骤 1. 创建Stream 流 得到 Stream流对象 常见的方式 是通过数据源得到的 2. 中间操作 中间的对Stream 流中的元素 一系列中间操作 比如 过滤 排序 映射 等等 3. 终止操作 一个终止操作 触发中间操作的执行 得到 最终的结果
/**
* @author GuoShuo
* @date 2022/6/28 16:22
*/
public class StreamDemo1 {
List<Student> list = Arrays.asList(
new Student(1,"zs",18,88.5),
new Student(2,"ls",14,89.5),
new Student(3,"ww",21,86.5),
new Student(4,"zl",19,98.5),
new Student(5,"tq",22,82.5),
new Student(6,"mb",21,83.5)
);
//首先理解流的核心概念
@Test
public void demo(){
list.stream()//得到流
.filter((s) -> s.getScore() > 90)//中间操作
//.map(Student::getName) //中间操作
.map((s) ->s.getName()) //中间操作
.forEach(System.out::println); //收尾操作
}
/**
*1.创建Stream流
*/
@Test
public void test1(){
//将集合转换为Stream流
Stream<Student> stream = list.stream();
List<String> strList = Arrays.asList("hello","java","springboot");
Stream<String> stream1 = strList.stream();
}
@Test
public void test2(){
//将数组转为Stream流
Student[] students = new Student[10];
students[0] = new Student();
Stream<Student> stream = Arrays.stream(students);
}
@Test
public void test3(){
//Stream流的静态方法
Stream<String> stringStream =Stream.of("zs","ls","ww");
}
@Test
public void test4(){
//通过Stream 的 iterator
Stream<Integer> stream =Stream.iterate(0,(x)-> x+2);
stream.forEach(System.out::println);
}
@Test
public void test5(){
// 通过Stream 的 generator
Stream<Double> stream = Stream.generate(() -> Math.random());
stream.forEach(System.out::println);
}
}
-------------------------------------------------------------------------------------- 流的中间操作 filter 过滤 重点掌握 limit 取值个数 distinct 去重 skip 跳过、 map 映射 重点掌握 sorted 排序 掌握
/**
* @author GuoShuo
* @date 2022/6/28 16:51
*
*
* 流的中间操作
* filter
*/
public class StreamDemo2 {
List<Student> list = Arrays.asList(
new Student(1,"zs",28,88.5),
new Student(2,"ls",24,89.5),
new Student(3,"ww",21,86.5),
new Student(4,"zl",19,98.5),
new Student(5,"tq",22,82.5),
new Student(6,"mb",21,83.5),
new Student(6,"mb",21,83.5)
);
@Test
public void test1(){
Stream<Student> stream = list.stream()
.filter((s) -> {
System.out.println("中间操作");
return s.getAge()>20;
});
stream.forEach(System.out::println);
}
@Test
public void test2(){
list.stream()
.filter((s) -> {
System.out.println("中间操作");
return s.getAge()>20;
}).limit(2) // 短路操作 不会把所有的数据 都过滤 再取两条 ,而是 取两条满足条件的 剩下的短路
.forEach(System.out::println);
}
@Test
public void test3(){
list.stream()
.filter((s) -> {
return s.getAge() > 20;
}
).distinct()
.forEach(System.out::println);
}
@Test
public void test4(){
list.stream()
.filter((s) -> {
return s.getAge() > 20;
}
).skip(2)
.forEach(System.out::println);
}
}
-----------------------------------------------------------------------------------------------------------------------------
Stream流的终止操作
/**
* @author GuoShuo
* @date 2022/6/28 17:07
*
* Stream流的终止操作
*/
public class StreamDemo3 {
List<Student> list = Arrays.asList(
new Student(1,"zs",28,88.5),
new Student(2,"ls",24,89.5),
new Student(3,"ww",21,86.5),
new Student(4,"zl",19,98.5),
new Student(5,"tq",22,82.5),
new Student(6,"mb",21,83.5),
new Student(6,"mb",21,83.5),
new Student(7,"zs1",28,88.5)
);
@Test
public void test1(){
// 查找 与 匹配 相关的终止操作
//boolean b = list.stream().allMatch(s -> s.getScore() > 90);
//boolean b = list.stream().anyMatch(s -> s.getScore() > 90);
//boolean b = list.stream().noneMatch(s -> s.getScore() > 90);
// 得到 成绩最高的 学生
Optional<Student> first = list.stream()
.sorted((s1,s2)->s1.getScore()>s2.getScore()?-1:1)
.findFirst();
//System.out.println(b);
System.out.println(first.get().getName());
}
@Test
public void test2(){
//count 统计流中的元素个数 统计90 以上的
//long count = list.stream()
// .filter((s)->s.getScore()>90)
// .count();
//
//System.out.println(count);
//max
Optional<Student> max = list.stream()
//.max((s1, s2) -> s1.getName().compareTo(s2.getName())); // 按照姓名比较
.max((s1,s2)-> s1.getAge()>s2.getAge()?1:-1); //查询 年龄最大的学生信息
System.out.println(max.get());
}
// 归约 和 收集 操作
@Test
public void test3(){
// Optional jdk8 为了避免空指针问题 在 对象的基础上 惊醒了 再次的封装
Optional<Double> result = list.stream()
.map(Student::getScore)
//.reduce((score1, score2) -> score1 + score2);
.reduce(Double::sum); // 统计 所有的 学生的成绩的和
System.out.println(result.get());
}
@Test
public void test4(){
// Optional jdk8 为了避免空指针问题 在 对象的基础上 惊醒了 再次的封装
Double result = list.stream()
.map(Student::getScore)
//.reduce((score1, score2) -> score1 + score2);
.reduce(100.0, Double::sum);// 统计 所有的 学生的成绩的和
System.out.println(result);
}
//使用 无限流 + 规约 计算 1到10 的 和
@Test
public void test5(){
Integer reduce = Stream.iterate(1, (x) -> x + 1) // 1 2 3 4 5 .......
.limit(100) // 1 2 3 .....100
.reduce(0, (x, y) -> x + y);
System.out.println(reduce);
}
@Test
public void test6(){
// 得到 90 分 以下的 学生的 名字 的集合
//ArrayList<String> collect = list.stream()
// .filter(s -> s.getScore() < 90)
// .map(Student::getName)
// //.collect(Collectors.toCollection(() -> new ArrayList<>()));
// .collect(Collectors.toCollection(ArrayList::new));
//LinkedHashSet<String> collect = list.stream()
// .filter(s -> s.getScore() < 90)
// .map(Student::getName)
// //.collect(Collectors.toCollection(() -> new ArrayList<>()));
// .collect(Collectors.toCollection(LinkedHashSet::new));
List<String> collect = list.stream()
.filter(s -> s.getScore() < 90)
.map(Student::getName)
//.collect(Collectors.toCollection(() -> new ArrayList<>()));
.collect(Collectors.toList());
System.out.println(collect);
}
}