JUC-04 (四大函数式,链式编程,流式计算,lambda表达式,异步回调)

四大函数简述(简写用lambda表达式):

java.util.function , Java 内置核心四大函数式接口,可以使用lambda表达式

消费型接口,有一个输入参数,没有返回值

public static void main(String[] args) {
//        Consumer<String> consumer=new Consumer<String>(){
//            @Override
//            public void accept(String s){
//
//             }
//        };
        // 简写
        Consumer<String> consumer = s -> { System.out.println(s);};
        consumer.accept("abc");
     }

//-----------------------------------------------------------------
//例子:forEach就是消费性函数接口
public class UnSafeList {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("a", "b", "c");
        list.forEach(System.out::println);
    }
}

//forEach源码
default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

供给型接口,没有输入参数,只有返回参数

public static void main(String[] args) {
        Supplier<String> supplier=new Supplier<String>(){
            @Override
            public String get(){
                return null;
            }
        };
        Supplier<String> supplier = ()->{return "abc";};
        System.out.println(supplier.get());
}

函数型接口,有一个输入,有一个输出

public static void main(String[]args){
// 函数式接口,可以改为 lambda 表达式
//  Function<String,Integer> function = new Function<String, Integer>() {
//      @Override
//      public Integer apply(String s) {
//              return 1024;
//          }
//      };
        // 简写
        Function<String, Integer> function=s->{return s.length();};
        System.out.println(function.apply("abc"));
     }

断定型接口,有一个输入参数,返回只有布尔值。

public static void main(String[] args) {
        Predicate<String> predicate=new Predicate<String>(){
            @Override
            public boolean test(String s){
                return false;
            }
        };
        // 简写
        Predicate<String> predicate = s -> {return s.isEmpty();};
        System.out.println(predicate.test("abc"));
}


Stream流式计算

流(Stream)到底是什么呢?

是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。
集合讲的是数据,流讲的是计算
特点
        Stream 自己不会存储元素。
        Stream 不会改变源对象,相反,他们会返回一个持有结果的新 Stream
        Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

测试代码

User 实体类
public class User {
    private int id;
    private String userName;
    private int age;
//get、set、有参/无参构造器、toString
}
Stream应用
/*
 * 题目:请按照给出数据,找出同时满足以下条件的用户
 * 也即以下条件:
 * 1、全部满足偶数ID
 * 2、年龄大于24
 * 3、用户名转为大写
 * 4、用户名字母倒排序
 * 5、只输出一个用户名字 limit
 **/
public class StreamDemo {
    public static void main(String[] args) {
        User u1 = new User(11, "a", 23);
        User u2 = new User(12, "b", 24);
        User u3 = new User(13, "c", 22);
        User u4 = new User(14, "d", 28);
        User u5 = new User(16, "e", 26);
        List<User> list = Arrays.asList(u1, u2, u3, u4, u5);
    /*
    * 1. 首先我们需要将 list 转化为stream流
    * 2. 然后将用户过滤出来,这里用到一个函数式接口Predicate<? super T>,我们可
    以使用lambda表达式简化
    * 3. 这里面传递的参数,就是Stream流的泛型类型,也就是User,所以,这里可以直接
    返回用户id为偶数的用户信息;
    * 4. 通过forEach进行遍历,直接简化输出 System.out::println ,等价于
    System.out.println(u);
    **/
        //1
        //list.stream().filter(u -> {return u.getId() % 2 == 0;}).forEach(System.out::println);
        //2
        //list.stream().filter(u -> {return u.getId()%2==0;}).filter(u -> {return u.getAge()>24;}).forEach(System.out::println);
        //sorted() 自然排序,正排序 D->E
        list.stream()
                .filter(u -> {
                    return u.getId() % 2 == 0;
                })
                .filter(u -> {
                    return u.getAge() > 24;
                })
                .map(u -> {
                    return u.getUserName().toUpperCase();
                })
                //.sorted() //默认正排序 自己用 compareTo 比较
                .sorted((o1, o2) -> {
                    return o2.compareTo(o1);
                })
                .limit(1)
                .forEach(System.out::println);

        //map解释
        List<Integer> list2 = Arrays.asList(1, 2, 3);
        
        list2 = list2.stream().map(x -> {
            return x * 2;
        }).collect(Collectors.toList());
        
        for (Integer element : list2) {
            System.out.println(element);
        }

    }
}

特别注意 排序:

升序

自然排序
list = list.stream().sorted().collect(Collectors.toList());
定制排序

根据年龄升序排序。

list = list.stream().sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList());

降序

自然排序

使用Comparator 提供的reverseOrder() 方法

list = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
定制排序

根据年龄降序排序。

list = list.stream().sorted(Comparator.comparing(Student::getAge).reversed()).collect(Collectors.toList());
多字段排序

先按姓名升序,姓名相同则按年龄升序。

list = list.sorted(Comparator.comparing(Student::getName).thenComparing(Student::getAge)).collect(Collectors.toList());

异步回调

简介
Future 的优点:比更底层的 Thread 更易用。 要使用 Future ,通常只需要将耗时的操作封装在一个
Callable 对象中,再将它提交给 ExecutorService
为了让程序更加高效,让 CPU 最大效率的工作,我们会采用异步编程。首先想到的是开启一个新的线程去做某项工作。再进一步,为了让新线程可以返回一个值,告诉主线程事情做完了,于是乎Future 粉墨登场。然而Future 提供的方式是主线程主动问询新线程,要是有个回调函数就爽了。所以,为了满足Future的某些遗憾,强大的 CompletableFuture 随着 Java8 一起来了。
实例 没有返回值runAsync /有返回值supplyAsync

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

public class CompletableFutureDemo {
    public static void main(String[] args) throws Exception {
        //没有返回值的 runAsync 异步调用
        CompletableFuture<Void> completableFuture =
                CompletableFuture.runAsync(() -> {
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "没有返回,update mysql ok");
                });
        System.out.println("111111"); // 先执行
        completableFuture.get();
        //有返回值的 供给型参数接口
        CompletableFuture<Integer> completableFuture2 =
                CompletableFuture.supplyAsync(() -> {
                    System.out.println(Thread.currentThread().getName() +
                            "completableFuture2");
                    int i = 10 / 0;
                    return 1024;
                });
        System.out.println(completableFuture2.whenComplete((t, u) -> { //编译完成,正常结束输出
            System.out.println("===t:" + t); //正常结果
            System.out.println("===u:" + u); //报错的信息
        }).exceptionally(e -> { //结果异常,非正常结束
            System.out.println("=======exception:" + e.getMessage());
            return 555;
        }).get());
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值