Stream API
一.概述
Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。
使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。
简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。
Stream 流 操作集合或数组
根据容器获取出一个流,使用流中提供的一个方法对集合中的元素进行一系列的流水线式的中间操作,获取一个持有新的结果的流
我们要使用Stream流分三个阶段
1.创建流
2.进行中间操作
3,中断操作
注意:
①Stream 自己不会存储元素。
②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
1.创建流
一个数据源(如:集合、数组),获取一个流
方式一:
集合中的stream方法
代码演示
List<Integer> list = Arrays.asList(10, 20, 30);
Stream<Integer> stream = list.stream();
方式二
Arrays中的静态方法可以获取一个流
代码演示
Stream<Integer> stream1 = Arrays.stream(new Integer[]{100, 200, 300});
方式三
stream的静态方法of()
代码演示
Stream<Integer> integerStream = Stream.of(30, 60, 90, 30);
方式四
创建一个无限流
代码演示
Stream<Integer> iterate = Stream.iterate(1, new UnaryOperator<Integer>() {
@Override
public Integer apply(Integer integer) {
return integer + 1;
}
});
//中间操作完了后,会返回一个持有结果的新流
Stream<Integer> iterate2 = iterate.limit(9);
//没有进行终止操作,中间环节,不执行,体现的是一种延迟加载的思想
iterate2.forEach(System.out::println);
方式五
创建一个无限流
Stream.generate(() -> Math.random()).limit(5).forEach(System.out::println);
2.进行中间操作
一个中间操作链,对数据源的数据进行处理
多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!
而在终止操作时一次性全部处理,称为“惰性求值”
(1).筛选与切片
1.过滤接收(filter)
从流中排除某些元素
代码演示
Stream<Employee> employeeStream = stream.filter(employee -> employee.getSalary() > 7000);
2.去重(distinct)
通过流所生成元素的 hashCode () 和 equals () 去除重复元素
代码演示
Stream<Employee> stream1 = stream.distinct();
3.截断流(limit)
使其元素不超过给定数量
代码演示
List<Integer> numbers = Arrays.asList(10, 20, 30,60);
Stream<? extends Number> stream = numbers.stream().limit(2);//从头开始截断几个元素
4.跳过元素(skip)
返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit (n)
代码演示
List<Integer> numbers = Arrays.asList(10, 20, 30,60);
Stream<? extends Number> stream2 = numbers.stream().skip(3);//跳过前几个元素
(2).映射
1.map(Function f)
接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
代码演示
List<String> strings = Arrays.asList("aaa", "bbb", "ccc");
Stream<String> stream1 = strings.stream();
//把集合中元素变大写
stream1.map(new Function<String, String>() {
@Override
public String apply(String s) {
String s1 = s.toUpperCase();
return s1;
}
}).forEach(System.out::println);
2.flatMap(Function f)
接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流.
代码演示
List<String> strings2 = Arrays.asList("aaa", "bbb", "ccc");
Stream<String> stream = strings2.stream();
Stream<Character> characterStream = stream.flatMap((e) -> getChar(e));
characterStream.forEach(System.out::println);
(3)排序
sorted()
产生一个新流,其中按自然顺序排序 元素实现Compareble接口
sorted(Comparator comp)
产生一个新流,其中按比较器顺序排序 传入一个比较
List<Integer> integers = Arrays.asList(10, 20, 30, 40,1,2);
Stream<Integer> stream = integers.stream();
//从大到小排序
stream.sorted((x,y)->Integer.compare(y,x)).forEach(System.out::println);
3.中断操作
1.allMatch(Predicate p)
检查是否匹配所有元素 比如判断 所有员工的年龄都是17岁 如果有一个不是, 就返回false
代码演示
List<Integer> integers = Arrays.asList(2,2,3);
boolean b = integers.stream().anyMatch((e) -> e >2);
System.out.println(b);//不是所有数都大于2故返回false
2.anyMatch(Predicate p)
检查是否至少匹配一个元素 比如判断是否有姓王的员工, 如果至少有一个就返回true
代码演示
List<Integer> integers = Arrays.asList(2,2,3);
boolean b = integers.stream().anyMatch((e) -> e >2);
System.out.println(b);//至少有一个3大于2返回ture
3.noneMatch(Predicate p)
检查是否没有匹配所有元素 比如判断所有员工的工资都是否都是高于3000 如果有一个人低于3000 就返回false
代码演示
List<Integer> integers = Arrays.asList(2,2,3);
boolean b = integers.stream().noneMatch((e) -> e >2);
System.out.println(b);//不是所有数都大于2故返回false
4.归约
1.reduce(T iden, BinaryOperator b)
参1 是起始值, 参2 二元运算 可以将流中元素反复结合起来,得到一个值。返回 T 比如求集合中元素的累加总和
代码演示
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer reduce = integers.stream().reduce(0, new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer a, Integer b) {
return a + b;
}
});
System.out.println(reduce);
2.reduce(BinaryOperator b)
这个方法没有起始值 可以将流中元素反复结合起来,得到一个值。返回 Optional, 比如你可以算所有员工工资的总和
代码演示
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> reduce = integers.stream().reduce(new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer a, Integer b) {
return a + b;
}
});
System.out.println(reduce.get());
备注map 和 reduce 的连接通常称为 map - reduce 模式,因 Google 用它来进行网络搜索而出名。
5.收集
代码演示
List<Employee> emps = Arrays.asList(
new Employee(102, "李四", 59, 6666.66),
new Employee(101, "张三", 18, 9999.99),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(104, "赵六", 8, 7777.77),
new Employee(105, "田七", 38, 5555.55)
);
1.收集到List集合
Stream<Employee> stream1 = emps.stream();
List<String> collect = stream1.distinct().map(e -> e.getName()).collect(Collectors.toList());
System.out.println(collect);
2.收集到set集合
Stream<Employee> stream2 = emps.stream();
Stream<String> stringStream = stream2.map(e -> e.getName());
Set<String> collect = stringStream.collect(Collectors.toSet());
System.out.println(collect);
3.收集到指定的集合
Stream<Employee> stream3 = emps.stream();
LinkedHashSet<String> collect = stream3.map(employee -> employee.getName()).collect(Collectors.toCollection(LinkedHashSet::new));
System.out.println(collect);