一,Lambda表达式的使用
1.举例:Comparator c= Comparator.comparingInt(o -> o);
2.格式:->:Lambda操作符
左边叫做形参列表,其实就是接口中的抽象方法的形参列表
右边叫做Lambda体(重写的抽象方法的方法体)
3.关于Lambda表达式的使用
总结:
-> 左边:lambda形参列表的参数类型可以省略(类型推断),如果形参列表只有一个参数,()可以省略。
-> 右边:Lambda体应该使用一对{}包裹,如果Lambda体只有一条执行语句(可能是return语句),{}和return也可以省略。
要求接口只有一个抽象方法。
4.Lambda表达式的本质:作为函数式接口的实例。
5.如果一个接口中只声明了一个抽象方法,则此接口称为函数式接口。
可以使用注解@FunctionalInterface检查是否是一个函数式接口。
用匿名实现类表示的现在都可以用Lambda表达式表示。
语法格式
/*** @author yhd* @createtime 2020/11/13 22:43*/public class DemoA {//语法格式一:无参数,无返回值@Testpublic void test1() {Runnable run = () -> System.out.println("语法格式一:无参数,无返回值");run.run();}//语法格式二:一个参数,无返回值@Testpublic void test2() {Consumer<String> consumer = args -> System.out.println(args);consumer.accept("语法格式二:一个参数,无返回值");}//语法格式三:Lambda 需要两个以上参数,多条执行语句,并且有返回值。@Testpublic void test3() {Comparator<Integer> comparable = (args1, args2) -> {System.out.println("args1 = " + args1);System.out.println("args2 = " + args2);return args1 > args2 ? 1 : (args1 == args2 ? 0 : -1);};System.out.println("comparable.compare(1,2) = " + comparable.compare(1, 2));}}
二,方法引用
Java内置四大核心函数式接口(要求能看懂)
消费性接口 Consumer void accept(T t)
供给型接口 Supplier T get()
函数型接口 Function
断定型接口 Predicate boolean test(T t)
使用情景:当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用。
方法引用:本质上就是Lambda表达式,而Lambda表达式作为函数式接口的实例,
所以方法引用,也是函数式接口的实例。
使用格式: 类(对象)::方法名
具体分为如下三种情况:
对象::非静态方法
类::静态方法
类::非静态方法
方法引用的使用要求,要求接口中的抽象方法的形参列表和返回值类型与方法引用
的方法的形参列表和返回值类型相同!
语法格式
/*** @author yhd* @createtime 2020/11/13 22:43*/public class DemoA {private static void run() {System.out.println("语法格式一:无参数,无返回值");}private static int compare(Integer args1, Integer args2) {System.out.println("args1 = " + args1);System.out.println("args2 = " + args2);return args1 > args2 ? 1 : (args1 == args2 ? 0 : -1);}//语法格式一:无参数,无返回值@Testpublic void test1() {Runnable run = DemoA::run;run.run();}//语法格式二:一个参数,无返回值@Testpublic void test2() {Consumer<String> consumer = System.out::println;consumer.accept("语法格式二:一个参数,无返回值");}//语法格式三:Lambda 需要两个以上参数,多条执行语句,并且有返回值。@Testpublic void test3() {Comparator<Integer> comparable = DemoA::compare;System.out.println("comparable.compare(1,2) = " + comparable.compare(1, 2));}//语法格式四:@Testpublic void test4(){Comparator<Integer>comparator= Integer::compareTo;System.out.println("comparator.compare(1,2) = " + comparator.compare(1, 2));}}
三,构造器引用
和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致,抽象方法的返回值类型就是构造器所属的类的类型。
数组引用
大家可以把数组看作一个特殊的类,则写法与构造器引用一致。
语法格式
/*** @author yhd* @createtime 2020/11/14 0:18*/public class DemoB {@Testpublic void test1(){BiFunction<String,String,Employee> emp = Employee::new;Employee employee = emp.apply("AA", "20");System.out.println("employee = " + employee);}@Testpublic void test2(){Supplier<Employee> emp = Employee::new;Employee employee = emp.get();System.out.println("employee.toString() = " + employee.toString());}@Testpublic void test3(){Function<Integer,Integer[]> params = Integer[]::new;Integer[] arrs = params.apply(5);System.out.println(Arrays.toString(arrs));}}@Data@NoArgsConstructor@AllArgsConstructorclass Employee{private String name;private String age;}
四,Stream
1.Stream关注的是数据的运算,与CPU打交道。
集合关注的是是数据的存储,与内存打交道。
2.
①Stream自己不会存储元素。
②Stream不会改变源对象,相反,他们会返回一个持有结果的新Stream。
③Stream操作是延迟执行的,这意味着它们会等到需要结果的时候才执行。
3.Stream的执行流程
①Stream的实例化
②一系列的中间操作(过滤,映射,。。。)
③终止操作
4.说明:
①一个中间链操作,对数据源的数据进行处理。
②一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用。
1.实例化
/*** @author yhd* @createtime 2020/11/14 20:18*/public class DemoC {/*** 流的4种实例化方式一:* 通过集合* 顺序流和并行流的区别:* 顺序流按照集合的顺序挨个取出元素* 并行流开多个线程去取,取出元素的顺序可能会发生变化*/@Testpublic void test1(){List<Integer> list=new ArrayList<>();//创建一个顺序流Stream<Integer> stream = list.stream();//创建一个并行流Stream<Integer> parallelStream = list.parallelStream();}/*** 流的4种实例化方式二:* 通过数组**/@Testpublic void test2(){Integer []a=new Integer[]{1,2,3,4,5,6};Stream<Integer> stream = Arrays.stream(a);}/*** 流的4种实例化方式三:* 通过of*/@Testpublic void test3(){Stream<Integer> stream = Stream.of(1, 2, 3);}/*** 流的4种实例化方式四:* 无限流*/@Testpublic void test4(){//迭代Stream.iterate(0,t->t+2).limit(10).forEach(System.out::print);//生成Stream.generate(Math::random).limit(10).forEach(System.out::print);}}
2,中间操作
1.过滤
/*** @author yhd* @createtime 2020/11/14 21:20*/public class Demo4 {private static List<Person> persons = new ArrayList<>();private static Stream<Person> stream;static {persons.add(new Person("1","马云",200.00));persons.add(new Person("2","马化腾",200.00));persons.add(new Person("3","李彦宏",200.00));persons.add(new Person("4","刘强东",200.00));persons.add(new Person("5","张朝阳",200.00));persons.add(new Person("5","张朝阳",200.00));stream = persons.stream();}//limit()截断取前面@Testpublic void test1() {stream.limit(2).forEach(System.out::println);}//filter()过滤出需要的元素@Testpublic void test2(){stream.filter(Demo4::test).forEach(System.out::println);}private static boolean test(Person person) {return person.getSalary() > 7000;}//skip()截断取后面@Testpublic void test3(){stream.skip(2).forEach(System.out::println);}//distinct()去除重复元素@Testpublic void test4(){stream.distinct().forEach(System.out::println);}}@Data@NoArgsConstructor@AllArgsConstructor@EqualsAndHashCodeclass Person implements Serializable {private String id;private String name;private Double salary;}
2.映射
/*** @author yhd* @createtime 2020/11/14 22:04*/public class DemoD {private static List<Person> persons = new ArrayList<>();private static Stream<Person> stream;static {persons.add(new Person("1", "马云", 200.00));persons.add(new Person("2", "马化腾", 200.00));persons.add(new Person("3", "李彦宏", 200.00));persons.add(new Person("4", "刘强东", 200.00));persons.add(new Person("5", "张朝阳", 200.00));stream = persons.stream();}/*** map和flatMap的区别:* list.add(list);* list.addAll(list);*/@Testpublic void test1() {stream.map(Person::getName).filter(e -> e.length() > 2).forEach(System.out::println);}@Testpublic void test2() {Arrays.asList("aa", "bb", "cc").stream().map(DemoD::StringToStream).forEach(DemoD::accept);Arrays.asList("aa", "bb", "cc").stream().flatMap(DemoD::StringToStream).forEach(System.out::println);}private static void accept(Stream<Character> e) {e.forEach(System.out::println);}public static Stream<Character> StringToStream(String str) {List<Character> result = new ArrayList<>();for (Character s : str.toCharArray())result.add(s);return result.stream();}}
3.排序
/*** @author yhd* @createtime 2020/11/14 22:41*/public class DemoE {private static List<Person> persons = new ArrayList<>();private static Stream<Person> stream;static {persons.add(new Person("1", "马云", 200.00));persons.add(new Person("2", "马化腾", 200.00));persons.add(new Person("3", "李彦宏", 200.00));persons.add(new Person("4", "刘强东", 200.00));persons.add(new Person("5", "张朝阳", 200.00));persons.add(new Person("5", "张朝阳", 200.00));stream = persons.stream();}@Testpublic void test1() {stream.sorted(DemoE::compare);}private static int compare(Person o1, Person o2) {return o1.getSalary() > o2.getSalary() ? 1 : (o1.getSalary() == o2.getSalary() ? 0 : -1);}}
3,终止操作
1.匹配与查找
/*** @author yhd* @createtime 2020/11/14 22:48* 终止操作:匹配与查找*/public class DemoF {private static List<Person> persons = new ArrayList<>();private static Stream<Person> stream;static {persons.add(new Person("1", "马云", 200.00));persons.add(new Person("2", "马化腾", 200.00));persons.add(new Person("3", "李彦宏", 200.00));persons.add(new Person("4", "刘强东", 200.00));persons.add(new Person("5", "张朝阳", 200.00));persons.add(new Person("5", "张朝阳", 200.00));stream = persons.stream();}//全部匹配返回true@Testpublic void test1() {System.out.println(stream.allMatch(p -> p.getSalary() > 100));}//任意匹配返回true@Testpublic void test2() {System.out.println(stream.anyMatch(p -> p.getSalary() > 100));}//都不匹配返回true@Testpublic void test3() {System.out.println(stream.noneMatch(p -> p.getSalary() > 300));}//获取流里面第一个@Testpublic void test4() {System.out.println(stream.findFirst().get());}//获取流里面随机一个@Testpublic void test5() {System.out.println(stream.findAny());}//获取流里面元素个数@Testpublic void test6() {System.out.println(stream.count());}//获取最大@Testpublic void test7() {System.out.println(stream.max(Comparator.comparing(Person::getSalary)).get());}//获取最小@Testpublic void test8() {System.out.println(stream.min(Comparator.comparing(Person::getSalary)).get());}}
2.归约
public class DemoF {private static List<Person> persons = new ArrayList<>();private static Stream<Person> stream;static {persons.add(new Person("1", "马云", 200.00));persons.add(new Person("2", "马化腾", 200.00));persons.add(new Person("3", "李彦宏", 200.00));persons.add(new Person("4", "刘强东", 200.00));persons.add(new Person("5", "张朝阳", 200.00));persons.add(new Person("5", "张朝阳", 200.00));stream = persons.stream();}@Testpublic void test9(){System.out.println(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream().reduce(10, Integer::sum));}@Testpublic void test10(){System.out.println(stream.map(Person::getSalary).reduce(0.0, Double::sum));}}
3.收集
collect(Collector())
Collector 接口中方法的实现决定了如何对流执行收集的操作。
Collectors实用类提供了很多静态方法,可以方便的创建常见的收集器实例。
/*** @author yhd* @createtime 2020/11/14 22:48**/public class DemoF {private static List<Person> persons = new ArrayList<>();private static Stream<Person> stream;static {persons.add(new Person("1", "马云", 200.00));persons.add(new Person("2", "马化腾", 200.00));persons.add(new Person("3", "李彦宏", 200.00));persons.add(new Person("4", "刘强东", 200.00));persons.add(new Person("5", "张朝阳", 200.00));persons.add(new Person("5", "张朝阳", 200.00));stream = persons.stream();}//列出员工的所有工资@Testpublic void test1(){stream.map(Person::getSalary).collect(Collectors.toList()).forEach(System.out::println);}//列出每个员工的工资@Testpublic void test2(){//System.out.println(stream.distinct().collect(Collectors.toMap(Person::getName, person -> person)));System.out.println(stream.distinct().collect(Collectors.toMap(Person::getName, Person::getSalary)));}}
五,Optional
Optional提供了很多有用的方法,这样我们就不用显示的进行空值检测。
1.创建Optional类对象的方法:
Optional.of(T t):创建一个Optional实例,t必须非空。
Optional.empty():创建一个空的Optional实例。
Optional.ofNullable(T t):t可以为null。
2.判断Optional容器中是否包含对象:
boolean isPresent() 判断是否包含对象
void ifPresent(Consumer<? super T> consumer):如果有值,就执行Consumer接口的实现代码,并且该值作为参数传给他。
3.获取Optional容器的对象
T get() 如果调用对象包含值,返回该值,否则抛出异常
T orElse(T other) 如果有值则将其返回,否则返回指定的other对象
T orElseGet(Supperlier<? super T> other) 如果有值则将其返回,否则返回由Supplier接口实现提供的对象。
T orElseThrow(Supperlier<? super X> exceptionSupplier) 如果有值则将其返回,否则抛出由Supplier接口实现提供的异常。
/*** @author yhd* @createtime 2020/11/15 0:44*/public class DemoG {@Testpublic void test() {Girl girl = new Girl();System.out.println(Optional.ofNullable(Optional.ofNullable(girl).orElseGet(Girl::new).getBoy()).orElseGet(Boy::new).getName());}}@Data@NoArgsConstructor@AllArgsConstructorclass Girl {private Boy boy;}@Data@NoArgsConstructor@AllArgsConstructorclass Boy {private String name;}
