Java学习日志(十四): 函数式接口详解,四种常见函数式接口

JavaEE学习日志持续更新----> 必看!JavaEE学习路线(文章总汇)

函数式接口

函数式接口的定义

函数式接口:有且仅有一个抽象方法的接口(可以包含:默认,私有,静态)

注意:函数式接口一般作为方法的参数使用

自定义一个函数式接口

@FunctionalInterface
public interface MyFunctionalInterface {
    //定义一个抽象方法
    public abstract void method();
}

@FunctionalInterface注解:检测一个接口是否为函数式接口

  • 是:接口中有且仅有一个抽象方法
  • 不是:代码会编译报错,接口中没有抽象方法,或抽象方法多于一个

函数式接口的使用

自定义函数式接口的实现类:

public class MyFunctionalInterfaceImpl implements MyFunctionalInterface{
    @Override
    public void method() {
        System.out.println("实现类重写的method方法");
    }
}

@Override注解:检测一个方法是否为重写的方法,如果不是,则会编译报错

三种方法使用函数式接口:
首先定义一个方法,方法的参数使用函数式接口MyFunctionalInterface

public static void show(MyFunctionalInterface my){
    my.method();
}
  1. 调用show方法,参数是一个接口,所以可以传递接口的实现类对象
public static void main(String[] args) {
    //调用show方法,参数是一个接口,所以可以传递接口的实现类对象
    show(new MyFunctionalInterfaceImpl());
}
  1. 调用show方法,参数是一个接口,所以可以传递接口的匿名内部类
public static void main(String[] args) {
       show(new MyFunctionalInterface() {
        @Override
        public void method() {
            System.out.println("匿名内部类执行的method方法");
        }
    });
}
  1. 调用show方法,参数是一个函数式接口,所以可以传递Lambda表达式
public static void main(String[] args) {
        show(()->{
            System.out.println("Lambda表达式执行的method方法");
        });
}

常用函数式接口

java.util.function

Supplier接口

java.util.Supplier<泛型>:用来生产数据

抽象方法
T get() 用来获取一个泛型参数指定类型的对象数据

作用:
Supplier接口指定什么泛型,就可以使用get方法,生产什么类型的数据

示例:

public class Demo01Supplier {
    /*
        定义一个方法,参数传递函数式接口Supplier,泛型使用String
        方法内部使用Supplier接口中的方法get,生产一个字符串并返回。

     */
    public static String getString(Supplier<String> sup){
        return sup.get();
    }

    public static void main(String[] args) {
        //调用getString方法,方法的参数是函数式接口,所以可以使用Lambda表达式重写get方法
        String s = getString(() -> {
            return "aaa";
        });
        System.out.println(s);
    }
}

练习:使用Supplier接口作为方法参数类型,通过Lambda表达式求出int数组的最大值

public class Demo02Supplier {
    /*
        定义一个方法
            参数传递Supplier接口,泛型使用Integer
            方法内使用Supplier接口的get方法返回数组的最大值
     */
    public static int getMax(Supplier<Integer> sup){
        return sup.get();
    }

    public static void main(String[] args) {
        //定义一个数组
        int[] arr = {11,-33,321312,433};
        //调用getMath方法
        int max = getMax(() -> {
            //获取数组最大值的过程
            int m = arr[0];
            for (int i = 1; i < arr.length; i++) {
                if (arr[i] > m) {
                    m = arr[i];
                }
            }
            return m;
        });
        System.out.println(max);
    }
}

Consumer接口

java.util.function.Consumer<泛型>:用于消费数据

抽象方法
void accept(T t) 消费一个指定泛型的数据

作用:
使用Consumer接口中的方法accept消费指定泛型的数据,至于怎么消费这个数据,需要自己定义(Lambda表达式中)

示例:

public class Demo01Consumer {
    /*
        定义一个方法,参数传递一个字符串,传递一个Consumer接口,泛型使用字符串
        方法内部使用Consumer接口中的方法accept消费传递的字符串
     */
    public static void print(String s, Consumer<String> con){
        con.accept(s);
    }

    public static void main(String[] args) {
        //调用print方法
        print("abc",(String s)->{
            System.out.println(s);
        });

        print("abc",(String s)->{
            //打印反向字符串
            System.out.println(new StringBuilder(s).reverse().toString());
        });
    }
}

默认方法
Consumer<T> andThen(Consumer<? super T> after)

源码:

default Consumer<T> andThen(Consumer<? super T> after) {
    Objects.requireNonNull(after);
    return (t) -> {
        this.accept(t);
        after.accept(t);
    };
}

作用:用于连接两个Consumer接口,一个是调用andThen方法的Consumer接口this,一个是andThen方法的参数after。

con1.andThen(con2).accept(s);等价于con1.accept(s);con2.accept(s);

示例:

public class Demo02 {
    /*
        定义一个方法
            参数传递字符串
            参数传递两个Consumer接口,泛型都使用字符串
     */
    public static void print(String s, Consumer<String> con1,Consumer<String> con2){
        //使用con1使用一次字符串
        //con1.accept(s);
        //使用con2使用一次字符串
        //con2.accept(s);
        //使用andThen方法连接两个consumer接口,再进行消费
        con1.andThen(con2).accept(s);//等价于con1.accept(s);con2.accept(s);
    }

    public static void main(String[] args) {
        //调用print方法
        print("abc",(String s)->{
            System.out.println(s+"正在洗碗");
        },(String s)->{
            System.out.println(s+"正在扫地");
        });
    }
}

Function接口

java.util.function.Function<T,R>:用于类型转换

抽象方法
R apply (T t) 根据类型T的参数获取类型R的结果

作用:把一种数据类型的数据,转换为另一种数据类型

示例:把String类型转换为Integer类型

public class Demo01 {
    /*
        定义一个方法
            参数传递一个字符串类型的整数
            参数传递Function<String,Integer>接口
     */
    public static void stringToInteger(String s, Function<String,Integer> fun){
        //使用apply方法进行类型转换
        Integer in = fun.apply(s);
        System.out.println(in);

    }

    public static void main(String[] args) {
        //调用stringToInteger方法
        stringToInteger("123",(String s)->{
            //把字符串类型的整数转化为Integer类型
            return Integer.parseInt(s);
        });
    }
}

练习:使用Function接口,传递字符串的姓名,返回Person类型的人

public class Demo02 {
    /*
        定义一个方法
            参数传递字符串的姓名
            参数传递Function<String,Person>接口
     */
    public static void stringToPerson(String name, Function<String,Person> fun){
        Person p = fun.apply(name);
        System.out.println(p);
    }

    public static void main(String[] args) {
        //调用stringToPerson方法
        stringToPerson("abc",(String name)->{
            return new Person(name);
        });
    }
}

默认方法Function<T, V> andThen(Function<? super R, ? extends V> after)

源码:

default Consumer<T> andThen(Consumer<? super T> after) {
    Objects.requireNonNull(after);
    return (t) -> {
        this.accept(t);
        after.accept(t);
    };
}

作用:把两个Function接口组合到一起,一个是调用andThen方法的Function接口this,另一个是andThen方法的参数Function接口after

after.apply(this.apply(t))

this先对数据进行转化,再把转化的结果作为after的参数再进行一次转化

fun1.andThen(fun2).apply(s);等价于
Integer in = fun1.apply(s);Integer in2 = fun2.apply(in);

示例:把String类型的"123",转化为Integer类型,把Integer类型123乘以10
“123”->123*10->1230

public class Demo03 {
    /*
        定义一个方法
            参数传递字符串类型的整数
            传递两个Function接口
     */
    public static void reverse(String s, Function<String, Integer> fun1, Function<Integer, Integer> fun2) {
        //"123"->123
        //Integer in = fun1.apply(s);
        //123*10
        //Integer in2 = fun2.apply(in);
        //使用andThen方法连接两个接口
        fun1.andThen(fun2).apply(s);
    }

    public static void main(String[] args) {
        //调用reverse方法
        reverse("123", (String s) -> {
            //"123"->123
            return Integer.parseInt(s);
        }, (Integer in) -> {
            //123*10
            return in * 10;
        });
    }
}

Predicate接口

java.util.function.Predicate<泛型>:用于数据判断

抽象方法
boolean test(T t) 对某种类型的数据进行判断,从而得到一个boolean值

作用:
Predicate接口指定什么泛型,就可以对什么类型的数据进行判断

示例:

public class Demo01 {
    /*
        定义一个方法
            参数传递一个字符串,参数传递Predicate接口,泛型使用String
     */
    public static void check(String s, Predicate<String> pre){
        //使用test方法,对字符串进行判断
        boolean b = pre.test(s);
        System.out.println(b);
    }

    public static void main(String[] args) {
        //调用check方法
        check("abc",(String s)->{
            //判断字符串是否包含a
            return s.contains("a");//true
        });

        check("abc",(String s)->{
            //判断字符串长度是否大于5
            return s.length()>5;//false
        });
    }
}

默认方法

  • Predicate<T> and(Predicate<? super T> other)
  • Predicate<T> or(Predicate<? super T> other)
  • Predicate<T> negate()

注意:

  • and方法与逻辑运算符&&功能相同
  • or方法与逻辑运算符||功能相同
  • negate方法与逻辑运算符!功能相同

代码等价示例:
定义一个方法参数传递字符串和两个Predicate接口,泛型都使用String

public static void check(String s, Predicate<String> pre1,Predicate<String> pre2){
	//方法体
}
  1. and
    boolean b = pre1.and(pre2).test(s);等价于
    boolean b = pre1.test(s) && pre2.test(s);
  2. or
    boolean b = pre1.or(pre2).test(s);等价于
    boolean b = pre1.test(s) || pre2.test(s);

定义一个方法参数传递字符串和一个Predicate接口,泛型使用String

public static void check(String s, Predicate<String> pre){
//方法体
}
  1. negate
    boolean b = !pre.test(s)等价于
    boolean b = pre.negate().test(s);
发布了36 篇原创文章 · 获赞 44 · 访问量 6711

猜你喜欢

转载自blog.csdn.net/Sakuraaaaaaa/article/details/104260379