函数式接口:只有一个方法的接口
- @FunctionalInterface
- public interface Runnable {
- public abstract void run();
- }
-
- //简化编程模型,在新版本的框架底层大量应用
- //foreach(消费者的函数式接口)


- /**
- * Function 函数型接口,有一个输入参数,有一个输出
- * 只要是函数型接口,可以用lambda表达式简化
- */
- public class demo01 {
- public static void main(String[] args) {
- // Function
function=new Function(){ - // @Override
- // public String apply(String o) {
- // return o;
- // }
- // };
- Function
function=(str)->{ - return str;
- };
- System.out.println(function.apply("asd"));
- }
- }

- /**
- * 断定型接口: 有一个输入参数,返回值只能是布尔值!
- */
- public class Demo02 {
- public static void main(String[] args) {
-
- // Predicate
predicate=new Predicate() { - // @Override
- // public boolean test(String o) {
- // if(o.isEmpty())
- // {
- // return true;
- // }
- // return false;
- // }
- // };
- Predicate
predicate=(str)->{ - return str.isEmpty();
- };
- System.out.println(predicate.test("123"));
- }
- }
- /**
- * Consumer 消费型接口:只有输入,没有返回值
- */
- public class demo03 {
- public static void main(String[] args) {
- // Consumer
consumer = new Consumer(){ - // @Override
- // public void accept(String s) {
- // System.out.println(s);
- // }
- // };
- Consumer
consumer=(s)->{ - System.out.println(s);
- };
- consumer.accept("yhy");
- }
- }

- /**
- * Suppiler 没有参数,只有返回值
- */
- public class demo04 {
- public static void main(String[] args) {
- // Supplier supplier=new Supplier
() { - // @Override
- // public String get() {
- // return "114514";
- // }
- // };
-
- Supplier supplier=()->{
- return "114514";
- };
- System.out.println(supplier.get());
- }
- }
集合,MySQL本质都是存储东西。计算交给流来操作。

在这个接口有如下方法

等等这些方法都是函数式接口。
- public class Test {
- public static void main(String[] args) {
- User u1=new User(1,"a",21);
- User u2=new User(2,"b",22);
- User u3=new User(3,"c",23);
- User u4=new User(4,"d",24);
- User u5=new User(5,"e",25);
- User u6=new User(6,"g",26);
- //集合存储
- List
list= Arrays.asList(u1,u2,u3,u4,u5,u6); - //计算交给Stream流
- //Lambda表达式、链式编程、函数式接口、Stream流式计算
- list.stream()
- .filter(u->{return u.getId()%2==0;})
- .filter(u->{return u.getAge()>23;})
- .map(u->{return u.getName().toUpperCase();})
- .sorted((uu1,uu2)->{return uu2.compareTo(uu1);})
- .limit(1)
- .forEach(System.out::println);
- }
- }
在jdk1.7,并行执行任务!提高效率。大数据量!
大数据:Map Reduce(把大任务拆分为小任务)

里面维护的都是双端队列。
两个线程执行任务,一个提前完成了就会去执行另一个的任务。


- /**
- * 求和计算任务
- * 3000 6000(forkjoin) 9000(Stream并行流)
- * //如何使用Forkjoin
- * //1.forkjoinpool
- * //2.计算任务forkjointaskPool.execute(ForkJoinTask>task)
- * //3.计算类继承RecursiveTask
- */
- public class ForkJoin extends RecursiveTask
{ - private Long start;
- private Long end;
-
- private Long temp=10000L;
-
- public ForkJoin(Long start, Long end) {
- this.start = start;
- this.end = end;
- }
-
- @Override
- protected Long compute() {
- if((end-start)
- Long sum = 0L;
- for(int i=0;i<10_0000_0000;i++)
- {
- sum+=i;
- }
- return sum;
- }else{
- //分支合并计算
- Long middle=(start+end)/2;//中间值
- ForkJoin task1=new ForkJoin(start,middle);
- task1.fork();//拆分任务,将任务压入线程队列。
- ForkJoin task2=new ForkJoin(middle+1,end);
- task2.fork();//拆分任务,将任务压入线程队列。
- return task1.join()+task2.join();
- }
- }
- }
这个玩意本质上就是的二分+递归,很简单的算法。
每二分一次线程数+1;各个线程执行不同段的计算任务。

- /**
- * 3000 6000(forkjoin) 9000(Stream并行流)
- */
- public class Test {
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- // test1(); //sum-243309312时间:9346
- // test2(); //8088?????? 好像也没快多少
- test3(); //700 究极快,最大限度利用CPU
- }
- public static void test1(){
- long start =System.currentTimeMillis();
- Long sum=0L;
- for(Long i=1L;i<=10_0000_0000;i++){
- sum+=i;
- }
- long end=System.currentTimeMillis();
- System.out.println("sum"+sum+"时间:"+(end-start));
- }
-
- //使用forkjoin
- public static void test2() throws ExecutionException, InterruptedException {
- long start =System.currentTimeMillis();
- ForkJoinPool forkJoinPool = new ForkJoinPool();
- ForkJoinTask
forkJoin = new ForkJoin(0L, 10_0000_0000L); - ForkJoinTask
submit=forkJoinPool.submit(forkJoin);//提交任务,有结果 - Long sum=submit.get();
- //forkJoinPool.execute(forkJoin);//执行,没有结果
- long end=System.currentTimeMillis();
- System.out.println("sum"+sum+"时间:"+(end-start));
- }
- //使用stream并行流
- public static void test3(){
- long start =System.currentTimeMillis();
- //(]
- LongStream.rangeClosed(0L,10_0000_0000L).parallel().reduce(0,Long::sum);
- long end=System.currentTimeMillis();
- System.out.println("sum"+"时间:"+(end-start));
- }
- }
异步回调(Future接口)
Future接口设计的初衷:对将来的事件进行建模。
前后端异步通信有ajax,java中也有异步通信。


- /**
- * 异步调用: CompltableFuture
- * //异步调用
- * //成功回调
- * //失败回调
- */
- public class demo01 {
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- // //没有返回值的异步回调
- // CompletableFuture
completedFuture = CompletableFuture.runAsync(()->{ - // try {
- // TimeUnit.SECONDS.sleep(2);
- // } catch (InterruptedException e) {
- // throw new RuntimeException(e);
- // }
- // System.out.println(Thread.currentThread().getName()+"runAsync=>void");
- // });
- // System.out.println("11111");
- // completedFuture.get(); //阻塞获取执行结果
- // System.out.println("22222");
-
- //有返回值的异步回调
- //ajax,成功和失败的回调
- //返回的是错误信息
- CompletableFuture
completedFuture =CompletableFuture.supplyAsync(()->{ - System.out.println(Thread.currentThread().getName()+" runAsync=>void");
- int t=10/0;
- return 1024;
- });
- System.out.println(completedFuture.whenComplete((t, u) -> {
- System.out.println("t=>"+t); //正常的返回结果
- System.out.println("u=>"+u); //抛出的错误信息
- }).exceptionally((e) -> {
- System.out.println(e.getMessage());//获取报错信息
- return 233; //获取到错误的返回结果
- }).get());
- }
- }
-
whenComplete(...)方法在CompletableFuture正常完成或遇到异常时均能执行。它接收两个参数,第一个参数是正常返回的结果(如果有),第二个参数是抛出的异常(如果有)。所以,这个方法中的输出语句会在CompletableFuture正常完成或遇到异常时都执行。
-
exceptionally(...)方法是用于处理异常情况的。如果CompletableFuture遇到异常,exceptionally(...)方法会被触发,并且它返回一个备用的结果。在你的代码中,exceptionally(...)方法中的代码会捕获到supplyAsync(...)中的异常(因为你在supplyAsync(...)中除以0了),然后输出异常信息并返回一个备用的结果(233)。因此,这个方法会执行,并输出异常信息。
综上所述,这句输出语句会执行是因为whenComplete(...)方法在正常或异常完成时都会执行,而exceptionally(...)方法会捕获异常并处理它,然后返回备用结果。