Stream API
1、定义
Stream API把真正的函数式编程风格引入到java中,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作,使用Stream API对集合数据进行操作,类似于使用SQL执行的数据库查询,集合是一种静态的内存结构数据,讲的是数据,而Stream是有关计算,讲的是计算。
2、Stream操作流程
现在有个EmployeeData数据
public class EmployeeData{
public static List<Employee> getEmployees(){
List<Employee> list = new ArrayList<>();
list.add(new Employee(1001,"马化腾1",34,6000));
list.add(new Employee(1002,"马化腾2",24,5000));
list.add(new Employee(1003,"马化腾3",14,8000));
return list;
}
}
步骤1:Stream的实例化
创建Stream方式一:通过集合
public void test1(){
List<Employee> list = EmployeeData.getEmployees();
//default Stream<E> stream():返回一个顺序流
Stream<Employee> stream = list.stream();
//default Stream<E> parallelStream():返回一个并行流
Stream<Employee> stream1 = list.paralStream();
}
创建Stream方式二:通过数组
public void test2(){
//调用Arrays类的static<T> Stream<T> stream(T[] array):返回一个流
Integer[] arr = new Integer[]{1,2,3,4,5};
Stream<Integer> stream = Arrays.stream(arr);
}
创建Stream方式三:通过Stream的of()
public void test3(){
Stream<String> stream = Stream.of("AA","BB","CC","DD");
}
步骤2:一系列的中间操作
1-筛选与切片
public void test1(){
//filter(Predicate p)--接收Lambda,从流中排除某些元素
//练习:查询员工表中薪资大于7000的员工信息
List<Employee> list = EmployeeData.getEmployees();
Stream stream = list.stream();
stream.filter(emp -> emp.getSalary() > 7000).forEach(System.out::println);
//limit(n)--截断流,使其元素不超过给定数量
//stream.limit(2).forEach(System.out::println);错误的,已经执行终止操作了
list.stream.limit(2).forEach(System.out::println);
//skip(n)--跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流
list.stream.skip(2).forEach(System.out::prinln);
//distinct()-筛选,通过流中生成元素的hashCode()和equals()去除重复元素
list.add(new Employee(1004,"马化腾4",56,16000));
list.add(new Employee(1004,"马化腾4",56,16000));
list.stream.distinct().forEach(System.out::println);
}
2-映射
public void test2(){
//map(Function f)--接收一个函数作为参数,将元素转换成其他形式或提取信息,该函数会被应用到每个元素上
//练习:转换为大写
List<String> list = Arrays.asList("aa","bb","cc","dd");
list.stream.map(str -> str.toUpperCase()).forEach(System.out::println);
list.stream.map(String::toUpperCase).forEach(System.out::println);
//练习:获取员工姓名长度大于3的员工的姓名
List<Employee> list = EmployeeData.getEmployees();
//方式一
list.stream.filter(emp -> emp.getName().length > 3).map(str -> str.getName()).forEach(System.out::println);
//方式二
list.stream.map(emp -> emp.getName()).filter(name -> name.length() > 3).forEach(System.out::println);
//方式三
list.stream.map(Employee:getName).filter(name -> name.length() > 3).forEach(System.out::println);
}
3-排序
public void test3(){
//sorted()--自然排序
Integer arr = new Integer[]{123,45,678,5,34,56,99};
String[] arr1 = new String[]{"GG","DD","HH","MM","SS"};
Arrays.stream(arr).sorted().forEach(System.out :: println);
System.out.println(Arrays.toString(arr));//arr数组并没有因为升序做调整
//sorted(Comparator com)--定制排序
List<Employee> list = EmployeeData.getEmployees();
list.stream().sorted((e1,e2) -> e1.getAge() - e2.getAge()).forEach(System.out :: println);
}
步骤3:执行终止操作
public class StreamAPITest2{
//1-匹配查找
public void test1(){
//allMatch(Predicate p)--检查是否匹配所有的元素
//练习:是否所有员工的年龄都大于18
List<Employee> list = EmployeeData.getEmployees();
System.out.println(list.stream.allMatch(emp -> emp.getAge() > 18));
//anyMatch(Predicate p)--检查是否至少匹配一个元素
//练习:是否存在员工的年龄大于18
System.out.println(list.stream.anyMatch(emp -> emp.getAge() > 18));
// findFirst--返回第一个元素
System.out.println(list.stream().findFirst());
public void test2(){
//count--返回流中元素的总个数
List<Employee> list = EmployeeData.getEmployees();
System.out.println(list.stream.filter(emp -> emp.getSalary() > 7000).count());
//max(Comparator c)--返回流中最大值
//min(Comparator c)--返回流中最小值
}
}
}