Java函数式编程
简介:
- 函数独立存在、方法属于类;
- Java中类是一等公民;
接口里的默认方法:
- 接口的默认方法可以有方法体(可以有多个默认方法):default 修饰;(实现类不需要实现默认方法);
- JDK1.8之前接口中不能有方法体;
- 可以在接口定义静态常量、静态方法(也可以有方法体)、在接口中定义的变量会默认成静态变量;
- 通过匿名内部类new接口:必须以匿名内部类的方式去new;相当于匿名内部类实现了接口,然后new的匿名内部类;
Lambda表达式:
- 语法:Class clazz(接收Lambda表达式返回值) = (参数)->{函数体}:若函数体只有一行语句,{}可以不写,若只有一个返回值return可以不写,参数为一个小括号也可不写;
1.函数式接口:
- 解释:仅仅包含一个方法一个抽象方法,但可以有多个非抽象方法(默认方法)的接口;
- 在接口上加@FunctionalInterface:函数式接口注解;
2.Lambda表达式作用域:
- 使用外部作用域变量(外部变量必须是final类型,Java8可以不声明为final但是含义也是final(不能被修改));
- 函数式编程相似于静态内部类(使用的外部作用域变量最好设置成final类型);
- 访问字段和静态变量:可以操作实例字段和静态变量,不能修改他们;
3.内置函数式接口:
- 常见有:Comparator(作比较)、Runnable;这些接口都加了@FunctionalInterface;
- Predicates:只有一个参数返回Boolean类型的断言型接口;只有一个test( T t )方法:传入某个值返回boolean;
- Functions:接收一个参数并生成一个结果有个apply();
- Suppliers:接口产生给定泛型的结果,只有一个get()方法不接受参数;
- Consumers:消费参数不返回任何值(存入数据库、打印都是消费)有一个accept()方法;
- Conparators:是老的Java经典接口,Java8在此接口中添加了多种默认方法;
Streams(流)
简介:
- 表示能够应用在一组元素上一次执行的操作序列,Stream分为中间操作和最终操作两种。最终操作返回特定类型的计算结果,而中间操作返回Stream本身,这样就可以将多次操作串联起来。Stream的创建需要指定一个数据源,比如Collection的子类,Map不支持。Stream的操作可以串行或并行执行。
操作方法:
-
转化成流:在Collection的子类后.stream()即可转化;后续操作链式调用即可(也可以直接用Collection子类调用流式方法);
-
Stream中传递的元素item:代表处理中的每个元素本身,写在Lambda表达式中时可以随意改名;
-
并行流:parallelStream();
- 常见中间操作:
- map(item->item*10):映射,需要传一个Functions类型的Lambda表达式,若item本身是2,经过map之后会映射成10,原因:map将Lambda表达式运算的结果映射给item元素本身;
- filter(item-> item >10):过滤,需要传一个断言型Lambda表达式,筛选每个元素,大于10则留下,不大于则过滤掉;
- sorted((num1,num2)->num1-num2):排序,传两个参数:num1-num2:升序,num2-num1:倒序;
- sort:优雅写法:person.sort(Comparator。comparingInt(person::getAge)):只调用一个方法可以不写Lambda表达式,直接,类名::方法,意思:根据年龄int值排序,若想倒序则在函数体=前加负号;
- 多条件排序:person.sort(Comparator。comparingInt(person::getAge).reversed().thenComparingInt(person::getHeight)),年龄倒序排列,若年龄一样则按身高升序排列;
- 并行流排序:parallelStream().sort(),多线程方式去处理流,效率高;
- distinct():去重,去除Stream中相同的元素;
- reduce((num1,num2)->num1+num2):规约,返回Integer,作用:把所有的元素相加返回最终结果;
- limit(Long maxSize):限制出来的元素个数;
- count():返回元素个数;
- toArray():将Stream转化成数组;
- 结束操作方法:
- collect(Collectors.toList () ):结束操作,将中间操作处理完的元素搜集起来转化成List集合并返回;
- forEach():简化写法:forEach(System.out :: println),直接将结果遍历打印;
新增时间类:
- 与SimpleDateFormat相比DateTimeFormatter是线程安全的;
- instant:可以精确到纳秒;