一、初步了解lamdba表达式
在jdk8之前我们方法参数都是基本数据类型或者引用数据类型,但是在8方法中可以传递函数表达式,即lamdba表达式,此表达式伟大在于既能兼容面向对象的调用也可以使用函数式编程,这是一个质的改变。传递值变成传递行为,这也是面向对象和函数式编程的区别。
1.表达式的使用
(type a,type b)->{需要执行的语句;}
一个type可以省略括号,多个type或者无参需要加括号,执行语句的只有一句则可以省略括号和;,省略后的为函数表达式。
2.@FunctionalInterface
这个叫“函数式接口”,看一下源码介绍
* Conceptually, a functional interface has exactly one abstract
* method. Since {@linkplain java.lang.reflect.Method#isDefault()
* default methods} have an implementation, they are not abstract. If
* an interface declares an abstract method overriding one of the
* public methods of {@code java.lang.Object}, that also does
* <em>not</em> count toward the interface's abstract method count
* since any implementation of the interface will have an
* implementation from {@code java.lang.Object} or elsewhere.
1.首先是个接口
2.只有一个抽象方法,如果实现了Object的方法,他的抽象方法不会加一。亲测确实这样
这样的类基本位于java.util.function包
3.Consumer
这是一个典型的函数式接口,他有两个方法
接口中也有实现方法,我们称他为默认方法。还有一个传入一个泛型T没有返回值的抽象方法。
为什么使用默认方法?
为了更好的向下兼容,比如老版本实现了list接口,你在接口中加入方法,会导致方法报错,需要手动去实现,而在接口中自己实现这个方法变成默认的方法就不需要要去改变之前的实现。
4.functon<T,R>
...
5.predicate
...
6.supplier
...
佛系作者,写哪算哪。
……
7.聊一下方法引用 method reference
为什么用方法引用?
lamdba表达式只有一行可以被替换的时候
1.类名::静态方法名
在类中有静态方法直接可以类名::静态方法名调用
2.引用名(对象名)::实例方法名
3.类名::实例方法名
一般调用实例方法都是对象.实例方法,在这里以第一个参数为对象去调用实例方法,其余的都为参数的形式进入方法
4.构造方法引用 类名::new
调用构造方法
二、stream介绍使用
为什么会有这个出现?
为了更好的操作集合,以一种函数式编程的方式去解决集合问题,这个流的出现和lamdba相辅相成的。
1.流构成的三部分
1.源
stream
-
0-多个中间操作
xxx,yyy的操作称为中间操作
3.终止操作
.count()成为终止操作
2.流操作的分类
1.惰性求值
如果,没有count呢莫该代码不执行
2.及早求值
需要立刻求出该操作的结果
stream.xxx.yyy.zzz().count()
3.报错问题
java.lang.IllegalStateException: stream has already been operated upon or closed
每一个流只能被处理一次,处理完成流会被关闭。链式中没操作一次都会创建新的流。
public static void main(String[] args) {
Student student1 = new Student("zhangsan",100,20);
Student student2 = new Student("lisi",80,23);
Student student3 = new Student("zhangsan",80,20);
List<Student> list = Arrays.asList(student1,student2,student3);
// 打印成绩最小
list.stream().min(Comparator.comparingInt(Student::getScore)).ifPresent(System.out::println);
// Map<String,List<Student>> map = list.stream().collect(Collectors.groupingBy(Student::getName));
// 成绩分组
// Map<Integer, List<Student>> collect = list.stream().collect(Collectors.groupingBy(Student::getScore));
// 计算每组多少人
// Map<String, Long> collect = list.stream().collect(Collectors.groupingBy(Student::getName, Collectors.counting()))
// 按照名字分组求出平均值
// Map<String, Double> collect = list.stream().collect(Collectors.groupingBy(Student::getName, Collectors.averagingInt(Student::getScore)));
// 分区
//Map<Boolean, List<Student>> collect = list.stream().collect(Collectors.partitioningBy(student -> student.getScore() >= 90));
//System.out.println(collect);
}
public static void main(String[] args) {
Student student1 = new Student("zhangsan",80);
Student student2 = new Student("lisi",90);
Student student3 = new Student("wangwu",100);
Student student4 = new Student("zhaoliu",90);
Student student5 = new Student("zhaoliu",90);
List<Student> list = Arrays.asList(student1,student2,student3,student4,student5);
// 打印成绩最小
//list.stream().collect(Collectors.minBy(Comparator.comparingInt(Student::getScore))).ifPresent(System.out::println);
// list.stream().collect(Collectors.)
// System.out.println(list.stream().map(Student::getName).collect(Collectors.joining()));
// System.out.println(list.stream().map(Student::getName).collect(Collectors.joining(",")));
// System.out.println("-----------------------------");
// Map<Integer, Map<String, List<Student>>> collect = list.stream().collect(Collectors.groupingBy(Student::getScore, Collectors.groupingBy(Student::getName)));
// System.out.println(collect);
// System.out.println("-----------------------------");
// Map<Boolean, Map<Boolean, List<Student>>> collect1 = list.stream().collect(Collectors.partitioningBy(student -> student.getScore() > 80, Collectors.partitioningBy(student -> student.getScore() > 90)));
// System.out.println(collect1);
// System.out.println("-----------------------------");
List<String> collect = list.stream().map(item -> item.getName()).collect(Collectors.toList());
Collections.sort(collect, Comparator.comparingInt(String::length));
System.out.println(collect);
}