• 8.函数式接口


    函数式接口
    概念:一个接口中的抽象方法只有一个,那么这个接口就是一个函数式接口。

    1、通过注解检测一个接口是否是一个函数式接口:

    @FunctionalInterface

    在接口上直接加上注解,如果这个接口是一个函数式接口则不报错,否则编译报错

    2、作用:

    (1)是Lambda表达式的使用前提

    (2)概念层面,为了表示接口就代表这个抽象方法,所以将名起为函数式接口

    内置函数式接口
    在jdk8之后,官方定义了一些常用的函数式接口,如果以后需要使用类似的接口,直接 使用即可,不需要再单独定义。

    分类:

    Consumer :消费型接口

    void accept(T t)

    Supplier :供给型接口

    T get()

    Function<T,R> :函数型接口

    R apply(T t)

    Predicate :断言型接口

    boolean test(T t);

    消费型接口
    接口名称:Consumer

    抽象方法:void accept(T t):消费一个参数数据

    概述:该接口中的方法可以接收一个参数,接收的参数类型由泛型指定,对参数的操作 方式根据该接口的实现类决定,不需要返回值。

    拓展的非抽象方法:

    default Consumer andThen(Consumer<? super T> after) :

    返回一个组合的 Consumer ,按顺序执行该操作,然后执行 after操作。

     1 public class consumer {
     2     public static void main(String[] args) {
     3         System.out.println("1、-----------------------------------");
     4         //想要打印的参数
     5         printNum("aaa",s -> System.out.println(s));
     6 
     7         System.out.println("2、-----------------------------------");
     8         //想要打印该参数字符的个数
     9         printNum("aaa",s -> System.out.println(s.length()));
    10 
    11         System.out.println("3、-----------------------------------");
    12         //将参数和其他字符串拼接
    13         printNum("aaa",s -> System.out.println("999"+s));
    14 
    15         System.out.println("4、-----------------------------------");
    16         Consumer<String> s1 = s -> System.out.println(s);
    17         Consumer<String> s2 = s -> System.out.println(s.length());
    18         //将s1 和 s2 结合到一起
    19         s1.andThen(s2).accept("aaa");
    20     }
    21     //方法的功能:打印参数
    22     // 打印好处:
    23     //          如果方法要使用一个参数,具体参数的使用方式不确定,或者有很多种使用方式
    24     //          可以将该参数交给消费型接口去完成该参数的使用
    25     //          后续使用该方法时,不仅要传递实际参数,还要传递消费型接口的实现类对象
    26     //          消费型接口的对象如何定义: 根据使用的具体需求来定义
    27     public static void printNum(String str, Consumer<String > con){
    28         con.accept(str);
    29     }
    30 }
    31 /*
    32 1、-----------------------------------
    33 aaa
    34 2、-----------------------------------
    35 3
    36 3、-----------------------------------
    37 999aaa
    38 4、-----------------------------------
    39 aaa
    40 3

    供给型接口
    1、接口名:Supplier :

    2、抽象方法:T get():该方法不需要参数,它会按照某种逻辑,返回一个具体的数据

    3、概述:

    该接口也被称为生产型接口,如果指定了泛型是什么类型,那类中的get方法就会返回 一个该类型的一个具体数据。返回的数据,由该接口的实现类对象决定。

     1 public static void main(String[] args) {
     2     //向集合中添加5个1-100之间的随机数并输出
     3     System.out.println(getList(() -> new Random().nextInt(100) + 1));
     4     //向集合中添加5个1-20之间的随机数并输出
     5     System.out.println(getList(() -> new Random().nextInt(20) + 1));
     6 }
     7 
     8 //定义一个方法:该方法可以返回一个Integer集合,该集合中的整数范围是:1-100,集合中右五个数据
     9 //              如果需要获取一个数据,但是返回的该数据不确定是谁
    10 //              可以使用供给型接口来使用该数据
    11 //              后续使用该方法时,需要根据调教来给出供给型接口的实现类对象(可以Lambda来实现)
    12 //              使用条件是谁,就怎么定义接口的实现类对象
    13 public static ArrayList<Integer> getList(Supplier<Integer> sup) {
    14     Random r = new Random();
    15     ArrayList<Integer> list = new ArrayList<>();
    16     for (int i = 0; i < 5; i++) {
    17         list.add(sup.get());
    18     }
    19     return list;
    20 }
    21 /*
    22 [86, 70, 81, 88, 57]
    23 [7, 16, 5, 9, 11]

    函数型接口
    1、接口名:Function<T,R>

    2、抽象方法:R apply(T):接收一个数据,操作数据之后,返回一个新的数据

    3、概述:

    该接口可以接收一个数据,数据的类型根据泛型指定,然后通过该接口的实现类对象对 该数据进行操作,操作之后返回一个新的数据。

    4、拓展的非抽象方法:default Function andThen(Function f):

    先通过调用者对象处理参数,将处理的结果再通过f对象处理,将两个处理的结果进行返回。

     1 public static void main(String[] args) {
     2     // 使用该方法时  第一点先传递该方法的参数1     【需要处理的数据】
     3     //             第二点要传递该数据的处理条件  【如何处理】
     4     System.out.println(function.strInt("aaa", s -> s.length()));
     5     System.out.println(function.strInt("123", s -> Integer.parseInt(s)));
     6     System.out.println("----------------------------------------------------");
     7 
     8     Function<String, String> fun1 = s -> "hello" + s;
     9     Function<String, Integer> fun2 = s -> s.length();
    10     //将 fun1 和 fun2 两种方式结合到一起
    11     Function<String, Integer> fun3 = fun1.andThen(fun2);
    12     //接收参数,之后,先使用fun1的方式处理,然后在使用fun2的方式处理,最终处理结果是返回值
    13     //将 abc 参数先通过 fun1 方式处理,返回值 helloabc。然后交给 fun2 方式处理 返回个数:8
    14     System.out.println(fun3.apply("abc"));
    15 }
    16 
    17 //定义一个方法 ,该方法可以接收一个字符串,返回该字符串的个数
    18 //                                 将该字符串转为对应的整数返回
    19 public static int strInt(String s, Function<String, Integer> fun) {
    20     return fun.apply(s);
    21 }
    22 /*
    23 3
    24 123
    25 ----------------------------------------------------
    26 8

    断言型接口
    1、Predicate:

    boolean test(T t):对数据做出指定的判断

    2、概述:

    该接口是一个判断接口,接口可以接收一个指定泛型的参数,并根据该接口的实现类 对象对该参数做出对应的判断,返回只为boolean类型

    3、额外功能:

    and(Predicate p):先将参数通过调用者判断真假,再将参数通过p判断真假,全真 为真,否则为假

    or(Predicate p):全假为假,否则为真

    negate():取反

     1 public static void main(String[] args) {
     2     ArrayList<String> st = new ArrayList<>();
     3     st.add("aac");
     4     st.add("bbc");
     5     st.add("ccc");
     6     
     7     //在使用该方法时,不仅需要给出需要处理的参数,也要给出判断条件
     8     //一旦条件给定之后,将来判断的结果就会随着条件的不同而改变
     9     System.out.println(is(st, s -> s.startsWith("a")));
    10     System.out.println(is(st, s -> s.length()==2));
    11     System.out.println("--------------------------------------------");
    12     Predicate<Integer> pre1 = s -> s >= 10 && s <= 100;
    13     Predicate<Integer> pre2 = s -> s >= 20 && s <= 80;
    14     //连接两个判断方式:全真为真,否则为假 ------ &
    15     System.out.println(pre1.and(pre2));
    16     //连接两个判断方式:全假为假,否则为真 ------ |
    17     System.out.println(pre1.or(pre2));
    18     //对某个结果取反
    19     System.out.println(pre1.negate());
    20 }
    21 
    22 //定义一个方法:  接受一个集合,判断该集合中的内容是否以a开头,如果全部都是,则返回真,否则返回假
    23 //                         判断字符串每个内容,长度是否满足都为2
    24 //             如果需要对数据进行判断,但是判断的规则不同,可以将需要判断的数据交给断言型接口去做
    25 public static boolean is(ArrayList<String> list, Predicate<String> pre) {
    26     for (String s : list) {
    27         if (!pre.test(s)) {
    28             return false;
    29         }
    30     }
    31     return true;
    32 }
    33 \*
    34 false
    35 false
    36 --------------------------------------------
    37 true
    38 true
    39 true

    方法引用
    1、概念:

    对lambda表达式的扩展,在定义lambda表达式的内容时,如果这个内容之前已经定 义过,那么就不需要再定义一遍,直接调用即可。

    2、格式:

    如果是一个构造方法:类名::new

    如果是一个静态方法:类名::方法名

    如果是一个非静态方法:对象名::方法名

     1 public class Demo04 {
     2     public static void main(String[] args) {
     3         //引用构造
     4         Consumer<String> con = Person::new;
     5         con.accept("宝贝");
     6         //引用静态
     7         Consumer<String> con1 = Person::show;
     8         con1.accept("宝贝");
     9         //引用非静态
    10         Consumer<String> con2 = new Person()::show1;
    11         con2.accept("宝贝");
    12     }
    13 }
    14 class Person{
    15     private String name;
    16 
    17     public Person() {
    18     }
    19 
    20     //构造方法
    21     public Person(String name){
    22         System.out.println(name+"你真好看!");
    23     }
    24     //静态方法
    25     public  static void show(String name){
    26         System.out.println(name+"你真好看!");
    27     }
    28     //非静态方法
    29     public void show1(String name){
    30         System.out.println(name+"你真好看!");
    31     }
    32 }
    33 /*
    34 宝贝你真好看!
    35 宝贝你真好看!
    36 宝贝你真好看!

    参考博客:https://blog.csdn.net/PIKapikaaaa/article/details/123487517

  • 相关阅读:
    JavaScript获取http,http://请求协议头,域名,端口,url
    JAVA Pattern正则获取大括号中内容,substring字符串截取获取大括号中内容
    系统时间相关
    简单搭建nfs
    电信电话相关
    windows常用设置
    sort用法
    vim查询替换相关
    vim常用命令 技巧
    编绎vim8.2+deepin v15.11
  • 原文地址:https://www.cnblogs.com/midiyu/p/16800641.html
Copyright © 2020-2023  润新知