一,为什么需要Stream?
实际开发中,项目中多数数据源都来自于 Mysql Oracle 等。但现在数据源可以更多了,有 MongDB Radis 等,而这些 NoSQL 的数据就 需要Java 层面去处理。 另外 Stream的使用需要创建,中间操作,终止操作三个步骤联合使用,缺一不可。
1.1 特性
- stream自己不会存储元素
- stream不会改变源对象,会返回一个持有新的stream
- stream 操作是延迟的
二,Stream使用步骤
2.1,创建方式
获取数据源,如从集合,数组中获取。
2.1.1 通过集合方式创建Stream
Java8中的 Collection 接口被扩展,提供了两个获取流的方法
default Stream<E> stream() : 返回一个顺序流
default Stream<E> parallelStream() : 返回一个并行流
2.1.2 通过数组方式创建Stream
Java8中的 Arrays 的静态方法 stream() 可以获取数组流:
static <T> Stream<T> stream(T[] array): 返回一个流 重载形式,能够处理对应基本类型的数组:
public static IntStream stream(int[] array)
public static LongStream stream(long[] array)
public static DoubleStream stream(double[] array)
2.1.3 通过Stream的of方法
可以调用Stream 类静态方法 of(), 通过显示值创建一个流。它可以接收任意数量的参数。
public static<T> Stream<T> of(T... values) : 返回一个流
2.2,中间操作
多个中间操作 可以连接起来形成一个 流水线 ,除非流水线上触发终止
操作,否则 中间操作不会执行任何的处理 !而在 终止操作时一次性全部处理,称为“惰性求值” 。
//filter(Predicate p) --接收lambda表达式,从流中排除某些元素
List<Employee> employees = EmployeeUtil.getEmployees();
employees.stream().filter(employee -> employee.getSalary()>100).
sorted((emp1,emp2) -> (int) (emp2.getSalary()-emp1.getSalary())).forEach(System.out::println);
//limit(n)截断流,使其元素不超过给定的数量
List<Employee> employees = EmployeeUtil.getEmployees();
employees.stream().sorted((emp1,emp2) -> (int) (emp2.getSalary()-emp1.getSalary())).limit(3).forEach(System.out::println);
//skip(n)跳过元素,返回一个扔掉前n个元素的流,若流中元素不足n个,则返回一个空流,与limit(n)互补
List<Employee> employees = EmployeeUtil.getEmployees();
employees.stream().skip(3).forEach(System.out::println);
//distinct()筛选,通过流生成元素hashcode()和equals(),去除重复元素
List<Employee> employees = EmployeeUtil.getEmployees();
employees.stream().distinct().forEach(System.out::println);
//判断所有的是否大于18
List<Employee> employees = EmployeeUtil.getEmployees();
boolean b = employees.stream().allMatch(e -> e.getAge() > 18);
System.out.println(b);
//是否存在一个员工的工资大于500
boolean b1 = employees.stream().anyMatch(emp -> emp.getSalary() > 500);
System.out.println(b1);
//是否存在一个员工的名字姓刘
boolean name = employees.stream().noneMatch(emp -> emp.getName().contains("刘"));
System.out.println(name);
//找出第一个元素
Optional<Employee> first = employees.stream().findFirst();
if(first.isPresent()) {
System.out.println(first.get());
}
//返回当前流中任意一个元素
System.out.println(employees.stream().findAny().get());
//count
long count = employees.stream().filter(emp -> emp.getSalary() > 200).count();
System.out.println(count);
2.3,终止操作
终止操作,执行中间链,并产生结果终端操作会从流的流水线生成结果。
其结果可以是任何不是流的值,例如: List 、 Integer ,甚至是void。
流进行中止后不能再次使用。