Java8常见函数式接口总结

   2023-02-08 学习力0
核心提示:函数式接口函数式接口:有且仅有一个抽象方法的接口。使用@FunctionalInterface注解来标记。如果接口不是函数式接口就会编译出错满足条件的接口即使不加上注解,那也是函数式接口函数式接口可以作为方法的参数public static void main(String[] args) {// 1.

函数式接口

  • 函数式接口:有且仅有一个抽象方法的接口。
  • 使用@FunctionalInterface注解来标记。如果接口不是函数式接口就会编译出错
  • 满足条件的接口即使不加上注解,那也是函数式接口
  • 函数式接口可以作为方法的参数
    public static void main(String[] args) {
            // 1. 匿名类作为参数
            startThread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            });
            // 2. 函数式接口作为参数
            startThread(() -> System.out.println(Thread.currentThread().getName()));
        }
    
        public static void startThread(Runnable r){
            new Thread(r).start();
        }
    
  • 函数式接口可以作为方法的返回值
    public static void main(String[] args) {
            // 函数式接口作为返回值
            List<String> list = new ArrayList<>();
            list.add("aa");
            list.add("bbbbb");
            list.add("c");
    
            System.out.println(list);
            Collections.sort(list, getComparator());
            System.out.println(list);
        }
    
        public static Comparator<String> getComparator(){
            // 1. 直接新建匿名对象
    //        Comparator<String> comp = new Comparator<String>() {
    //            @Override
    //            public int compare(String o1, String o2) {
    //                return o1.length() - o2.length();
    //            }
    //        };
    //        return comp;
    
            // 2. 使用lambda
            Comparator<String> comp = (o1, o2) -> o1.length() - o2.length();
            return comp;
        }
    

常用的函数式接口

  • Supplier<T>: 没有输入,返回一个T类型的结果。
  • Consumer<T>: 输入一个 T 类型参数,没有返回值。
  • Predicate<T>: 输入一个T类型参数,返回boolean。
  • Function<T, R> : 输入一个T类型参数,返回R类型参数。

对应的还有两个参数的版本:

  • BiConsumer<T, U>: 输入是 TU 类型的数据,无返回值
  • BiPredicate<T, U>: 输入是 TU 类型的数据,返回 boolean 类型。
  • BiFunction<T, U, R>: 输入是 TU 类型的数据,返回 R 类型。

Function<T, R> 接口

@FunctionalInterface
public interface Function<T, R> {
    
    // 输入T类型参数,输出R类型结果
    R apply(T t);

    // 返回一个新的Function。先执行before,再执行当前 
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    // 返回一个新的Function。限制性当前,再执行after
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    static <T> Function<T, T> identity() {
        return t -> t;
    }
}
    Function<String, String> func1 = (x) -> x + "1";
    Function<String, String> func2 = (x) -> x + "2";
    
    System.out.println(func1.apply("0"));                   // 01
    System.out.println(func1.andThen(func2).apply("0"));    // 012
    System.out.println(func1.compose(func2).apply("0"));    // 021

Consumer<T> 接口

@FunctionalInterface
public interface Consumer<T> {

    void accept(T t);


    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}
    Consumer<StringBuilder> consumer = (x) -> {
        x.append("1");
    };
    StringBuilder str = new StringBuilder("0");
    consumer.accept(str);
    System.out.println(str.toString());         // 01

Supplier<T> 接口

@FunctionalInterface
public interface Supplier<T> {
    
    // 获取一个元素
    T get();
}

lambda可捕获局部变量

    // Suplier
    Supplier<String> supplier = () -> "aaa";
    System.out.println(supplier.get());

    // 使用外部变量
    int arr [] = {20, 40, 30, 10};
    Supplier<Integer> getMax = ()-> {
        int max_ = arr[0];
        for (int item : arr){
            if (item > max_)    max_ = item;
        }
        return max_;
    };
    System.out.println(getMax.get());

Predicate<T> 接口

@FunctionalInterface
public interface Predicate<T> {

    // 输入一个t,返回boolean
    boolean test(T t);

    // 与运算
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    // 取反运算
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    // 或运算
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}
    // Predicate
    Predicate<String> predicate = (x)-> x.contains("0");
    Predicate<String> predicate2 = (x) -> x.contains("1");

    System.out.println(predicate.test("0123"));                     // true
    System.out.println(predicate.negate().test("0000"));            // false
    System.out.println(predicate.and(predicate2).test("0123"));     // true
    System.out.println(predicate.or(predicate2).test("0000"));      // true
 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • Java项目导出数据为 PDF 文件的操作代码
    Java项目导出数据为 PDF 文件的操作代码
    目录Java项目如何导出数据为 PDF 文件?一、代码结构如下二、代码说明1、添加依赖 pom.xml2、HTML模板文件 audit_order_record.html3、添加字体4、PDF 导出工具类5、导出接口6、打开浏览器测试三、效果图Java项目如何导出数据为 PDF 文件?一个小需求,需要将
  • 盘点Java中延时任务的多种实现方式 java 延时队列怎么实现
    盘点Java中延时任务的多种实现方式 java 延时队
    目录场景描述实现方式一、挂起线程二、ScheduledExecutorService 延迟任务线程池三、DelayQueue(延时队列)四、Redis-为key指定超时时长,并监听失效key五、时间轮六、消息队列-延迟队列场景描述①需要实现一个定时发布系统通告的功能,如何实现? ②支付超时
  • Java Semaphore信号量使用分析讲解
    Java Semaphore信号量使用分析讲解
    目录前言介绍和使用API介绍基本使用原理介绍获取许可acquire()释放许可release()总结前言大家应该都用过synchronized 关键字加锁,用来保证某个时刻只允许一个线程运行。那么如果控制某个时刻允许指定数量的线程执行,有什么好的办法呢? 答案就是JUC提供的信
  • 【Java并发入门】03 互斥锁(上):解决原子性问题
    【Java并发入门】03 互斥锁(上):解决原子性
    原子性问题的源头是线程切换Q:如果禁用 CPU 线程切换是不是就解决这个问题了?A:单核 CPU 可行,但到了多核 CPU 的时候,有可能是不同的核在处理同一个变量,即便不切换线程,也有问题。所以,解决原子性的关键是「同一时刻只有一个线程处理该变量,也被称
    02-09
  • Java限流实现的几种方法详解 限流的实现方式
    Java限流实现的几种方法详解 限流的实现方式
    目录计数器信号量滑动窗口漏桶令牌桶测试示例代码计数器计数器限流方式比较粗暴,一次访问就增加一次计数,在系统内设置每 N 秒的访问量,超过访问量的访问直接丢弃,从而实现限流访问。具体大概是以下步骤:将时间划分为固定的窗口大小,例如 1 s;在窗口时间
    02-09 Java限流
  • Java多线程Thread类的使用详解
    Java多线程Thread类的使用详解
    目录1.创建一个线程2.start()方法与run()方法3.查看线程4.创建线程的各种方法4.1实现Runnable接口4.2使用匿名内部类4.3使用匿名内部类实现Runnable4.4使用Lambda表达式1.创建一个线程Java操作线程最核心的类就是Thread类创建线程有很多方法,下面我们写一个Myt
  • java如何读取某个文件夹中的全部文件(包括子文件夹)
    java如何读取某个文件夹中的全部文件(包括子文
    目录java读取某个文件夹中的全部文件主要思路示例java获取文件夹下指定的文件java读取某个文件夹中的全部文件主要思路使用file.listFiles()函数可以获取到某文件夹下的所有文件信息,如果需要访问子文件夹下的文件,则需要对获取到的文件信息进行递归遍历,如
  • Java开发学习(四十六)----MyBatisPlus新增语句之id生成策略控制及其简化配置
    Java开发学习(四十六)----MyBatisPlus新增语句
    在前面有一篇博客:Java开发学习(四十一)----MyBatisPlus标准数据层(增删查改分页)开发,我们在新增的时候留了一个问题,就是新增成功后,主键ID是一个很长串的内容。我们更想要的是按照数据库表字段进行自增长,在解决这个问题之前,我们先来分析下ID该如
    02-09
  • Java数据结构之KMP算法详解以及代码实现
    Java数据结构之KMP算法详解以及代码实现
    目录暴力匹配算法(Brute-Force,BF)概念和原理next数组KMP匹配KMP全匹配总结我们此前学了前缀树Trie的实现原理以及Java代码的实现。Trie树很好,但是它只能基于前缀匹配实现功能。但是如果我们的需求是:一个已知字符串中查找子串,并且子串并不一定符合前
  • Java数据结构之AC自动机算法的实现 ac自动机算法
    Java数据结构之AC自动机算法的实现 ac自动机算
    目录1 概念和原理2 节点定义3 构建Trie前缀树4 构建fail失配指针5 匹配文本6 案例演示7 总结1 概念和原理一般的字符串匹配算法都是匹配一个子串,例如KMP、Trie,那么如果同时匹配多个子串呢?此时就需要用到AC自动机了。AC自动机算法是一个多模式字符串匹配
点击排行