推导lambda表达式
匿名函数,用于接口
public class TestLambda {public void test1() {/* Comparator<Integer> comparator = new Comparator<Integer>(){@Overridepublic int compare(Integer o1, Integer o2) {return Integer.compare(o1,o2);}};TreeSet<Integer> set =new TreeSet<Integer>(comparator);*/TreeSet<Integer> set = new TreeSet<>((x,y)->Integer.compare(x, y));}}
package Dome;/*推导lambda表达式*//*** @author dafran* @version 1.0* @date 2020-05-24 17:18*/public class TestLambda01 {//3.静态内部类static class Like2 implements ILike {@Overridepublic void lambda() {System.out.println("This is Lambda2");}}public static void main(String[] args) {ILike like = new Like();like.lambda();like = new Like2();like.lambda();//4.局部内部类class Like3 implements ILike {@Overridepublic void lambda() {System.out.println("This is Lambda3");}}like = new Like3();like.lambda();//5.匿名内部类,没有类的名称,必须借助接口或者父类like = new ILike() {@Overridepublic void lambda() {System.out.println("This is Lambda4");}};like.lambda();//6.用Lambda简化like = ()->{System.out.println("This is Lambda5");};like.lambda();}}//1.定义一个函数式接口interface ILike{void lambda();}//2.实现类class Like implements ILike {@Overridepublic void lambda() {System.out.println("This is Lambda");}}
lambda表达式简化
package Dome;/*** @author dafran* @version 1.0* @date 2020-05-24 17:47*/public class TestLambda02{public static void main(String[] args) {ILove love = null;//1.Lambda简化love = (int a) ->{System.out.println("This is Love->" + a);};//2.参数简化love = (a) ->{System.out.println("This is Love->" + a);};//3.简化括号love = a -> {System.out.println("This is Love->" + a);};//4.简化花括号love = a -> System.out.println("This is Love->" + a);// 总结:// lambda表达式只能有一行代码的情况下才能简化成为行,如果有多行, 那么就用代码块包// 前提是接口为函数式接口// 多个参数也可以去掉参数类型,要去掉就都去掉,必须加上括号love.love(520);}}interface ILove{void love(int a);}
六大语法
”->“;
- 左侧:Lambda表达式的参数列表
- 右侧:Lambda表达式中所执行的功能,Lambda体
- 依赖于函数式接口,Lambda表达式即对接口的实现
public class LearnLambda {/** 语法一:无参、无返回值* 里面的变量和匿名内部类的相同,默认为final* 需要可以设数组*/public void test01() {Runnable runnable = ()->{System.out.println("1");};Runnable runnable =new Runnable() {@Overridepublic void run() {System.out.println("1");}};}}/**************************************//** 语法二:有一个参数、无返回值*/public void test02() {/* Consumer<String> com = (x)->{System.out.println(x);};com.accept("test02");}*/Consumer<String> com = new Consumer();this.change(com);System.out.println(com);};public void change(Consumer com) {com.accept("test02");}}/**//*******/public class LearnLambda {/** 语法三:只有一个参数,省略括号**/public void test03(){Consumer<String> com= x->{ System.out.println(x);};com.accept("003");}}/************************//** 语法四:两个以上的参数,有返回值,并且Lambda体中有多条语句**/public void test04(){Comparator<Integer> com = (x,y) -> {System.out.println("1234");return Integer.compare(x,y);};}/*****************/public class LearnLambda {/** 语法五:Lambda体只有一条语句,return和大括号可以不写**/public void test05(){Comparator<Integer> com = (x,y) -> Integer.compare(x,y);}}/**********************/public class LearnLambda {/** 语六:参数指定类型**/public void test06(){Comparator<Integer> com = (Integer x,Integer y) -> Integer.compare(x,y);}}
四大内置函数
| 类型 | 类 | 抽象方法 |
|---|---|---|
| 消费型接口(一个参数,无返回值) | Consumer | void accept(T t); |
| 供给型接口(无参数,有返回值) | Supplier | T get(); |
| 函数型接口(一个参数,有返回值) | Function |
R app1y(T t); |
| 断言型接口(有参数,返回值为boolean类型) | Predicate | boolean test(T t); |
import org.junit.jupiter.api.Test;import java.util.ArrayList;import java.util.List;import java.util.function.Consumer;import java.util.function.Function;public class StudyLambda {//消费型接口Consumer//需求:传入一个参数做业务处理,不做返回值public void happy(double money,Consumer<Double> con){con.accept(money);}@Testpublic void test1(){happy(1000, (m) -> System.out.println("每次消费"+m+"元"));}//供给型接口Supplier//需求:产生指定数量的整数,放到集合中,返回集合public List<Integer> getNumList(int num, java.util.function.Supplier<Integer> sp){List<Integer> resurlt = new ArrayList<>();for (int i = 0; i < num; i++) {resurlt.add(sp.get());}return resurlt;}@Testpublic void test2(){List<Integer> numList = getNumList(5,() -> (int) (Math.random() * 100));numList.forEach(System.out::println);}//函数型//需求:传入一个字符串,返回一个字符串public String strHandler(String str, Function<String, String>fun){return fun.apply(str);}@Testpublic void test3(){String result = strHandler("武林盟主",(x) -> x+"无忌老师");System.out.println(result);}//断言型//Predicate}
/*下面的不是很懂*/class StudyLambda03{/*方法引用和对象引用* 若Lambda体中的内容有方法实现,我们可以使用“方法引用”* 可以理解为方法引用是Lambda表达式的另一种表现形式* *///对象::实例方法名@Testpublic void test4(){//Consumer<String> con = (x) -> System.out.println(x);PrintStream printStream = System.out;//注意的是接口的抽象方法的形参表、返回值类型需要和调用的类方法形参表 返回值类型保持一致Consumer<String> con = System.out::println;con.accept("123456");}//类::静态方法名@Testpublic void test5(){//注意的是接口的抽象方法的形参表、返回值类型需要和调用的类方法形参表 返回值类型保持一致Comparator<Integer> com = (x,y) -> Integer.compare(x, y);Comparator<Integer> com2 = Integer::compare;}//类::实例方法名@Testpublic void test6(){//需求一:比较两个字符串是否相等;//要求:第一参数是实例方法的调用者,第二个参数是方法的传入参数时BiPredicate<String, String> bp = (x,y) -> x.equals(y);BiPredicate<String, String> bp2 = String::equals;}//构造器引用//此处自己新建类@Testpublic void test7(){Supplier<Person> student = Person::new;Person person = student.get();Function<Integer, Person> student = Person::new;Person apply = student.apply(25);System.out.println(apply.getAge());}}
Stream
Stream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用StreamAPI对集合数据进行操作,就类似于使用SQL执行的数据库查询。也可以使用StreamAPl来并行执行操作。
简而言之,StreamAPI提供了一种高效且易于使用的处理数据的方式。

import org.junit.jupiter.api.Test;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.stream.Stream;public class StreamApi {//需求:学员年龄大于25岁的List<Person> studentList = Arrays.asList(new Person("无极","18","181","35000");new Person("无极1","18","181","35000");new Person("无极2","18","181","35000");new Person("无极3","18","181","35000");new Person("无极4","18","181","35000"))//创建流//四种@Testpublic void test(){List<String> list = new ArrayList<>();Stream<String> stream = list.stream();Person[] students = new Person[]{};Stream<Person> stream1 = Arrays.stream(students);Stream<String> stream = Stream.of("a","b","c");Stream<Integer> stream4 = Stream.iterate(0,(x) -> x+2);stream4.limit(10).forEach(System.out::println);}//终止操作:一次性执行全部内容 --> "惰性求值"@Testpublic void test2(){Stream<Person> studentStream = studentList.stream().filter((x) -> x.getSlary() -> 25000);studentStream.forEach(System.out::println);}//map 映射 接收Lambda,将元素转换成其他形式或提取信息。//接受一个函数作为参数,该函数会被应用到每个元素上并其映射成一个新的元素@Testpublic void test3(){Stream<String> stream = Stream.of("aaa","bbb","ccc");stream.map((x) -> x.toUpperCase()).forEach(System.out::println);//studentList.stream().map(Person::getName).forEach(System.out::println);}}
并行流和串行流
并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。Java8中将并行进行了优化,我们可以很容易的对数据进行并行操作。Stream API可以声明性地通过parallel()与sequential()在并行流与顺序流之间进行切换。
import org.junit.jupiter.api.Test;import java.time.Duration;import java.time.Instant;import java.util.stream.LongStream;/*** @author Administrator* @Classname StreamApi2* @Description TODO* @Date 2020-10-04 21:24* @Version V1.0*/public class StreamApi2 {@Testpublic void test(){Instant start = Instant.now();long res = LongStream.rangeClosed(0,1000000L).parallel().reduce(0,Long::sum);System.out.println(res);Instant end = Instant.now();System.out.println("耗费事件为:"+ Duration.between(start, end).toMillis());}}
ForkJoin并发框架从JDK1.7开始,Java提供ForkJoin框架用于并行执行任务,它的思想就是讲一个大任务分割成若干小任务,最终汇总每个小任务的结果得到这个大任务的结果。
两个特性:递归分治、工作密取
引出Stream
import java.util.concurrent.RecursiveTask;/*** @author Administrator* @Classname ForkJoinCalculate* @Description TODO* @Date 2020-10-04 20:43* @Version V1.0*/public class ForkJoinCalculate extends RecursiveTask {private long start;private long end;private static final long THRESHOLD = 10000;public ForkJoinCalculate(long start, long end){this.start = start;this.end = end;}/*** 运算或者任务拆分**/@Overrideprotected Object compute() {long length = end - start;if (length <= THRESHOLD) {//当前任务数据区间小于10000long sum = 0;for (long i = start; i <= end; i++){sum += i;}return sum;}else {//当前任务数据区间大于10000long middle = (start + end) / 2;ForkJoinCalculate left = new ForkJoinCalculate(start,middle);ForkJoinCalculate rigth = new ForkJoinCalculate(middle+1,end);left.fork();rigth.fork();return left.join() + rigth.join();}}}
