Java:函数式接口、方法引用

1、函数式接口-概念及格式

函数式接口:有且只有一个抽象方法的接口(可以有其他的方法:默认方法,静态方法,私有方法…)

2、函数式接口-@FunctionalInterface注解

1)、在定义函数式接口时,为防止发生定义错误,可使用@FunctionalInterface注解,强制按照函数式接口的语法进行检查,如果语法错误,编译器会编译错误

@FunctionalInterface
interface IA{//如果此接口不定义任何抽象方法,将会报错
	public void show();
	public void show1();//如果此接口定义多个抽象方法,也会报错
}

3、函数式接口-练习-自定义函数式接口(无参无返回值)

//无参,无返回值的函数式接口
@FunctionalInterface
interface IA{
    public void show();
}

public class Demo {
    public static void main(String[] args) {        
        //2.使用Lambda表达式,代替"匿名内部类"
        fun(() -> System.out.println("呵呵...."));
    }
    public static void fun(IA a){
        a.show();
    }
}

4、函数式接口-练习-自定义函数式接口(有参有返回值)

@FunctionalInterface
interface IA{
    public int calc(int a, int b);
}
public class Demo {
    public static void main(String[] args) {
        //2.使用Lambda
        fun((int m, int n) -> {
            return m + n;
        }, 10, 20);
    }

    public static void fun(IA a, int x, int y) {
        int result = a.calc(x, y);
        System.out.println("结果是:" + result);
    }
}

5、函数式编程-Lambda的应用-延迟执行

@FunctionalInterface
interface IA{
    public String buildString();
}
public class Demo {
    public static void main(String[] args) {
        String s1 = "日志级别:1";
        String s2 = "异常信息:NullPointerException";
        String s3 = "日期:2018-09-22";
        //1.使用匿名内部类的方式
        fun(1, new IA(){
            @Override
            public String buildString() {
                System.out.println("执行了....");
                return s1 + s2 + s3;
            }
        });

        //2.使用Lambda代替匿名内部类
        fun(1,()->{
            System.out.println("执行啦.....");
            return s1 + s2 + s3;});

    }

    //一个打印日志
//    public static void fun(int level, String msg) {//原方法
    public static void fun(int level, IA a) {//改为接口类型形参
        if (level == 1) {//只有级别为1时,才打印日志--延迟
            System.out.println(a.buildString());
        }
    }
}

6、函数式编程-Lambda的应用-自定义接口-Lambda作为参数和返回值

@FunctionalInterface
interface IA{
    public void show();
}
public class Demo {
    public static void main(String[] args) {
        //Lambda作为形参
        f1(() -> System.out.println("呵呵呵"));
        //Lambda作为返回值
        IA a = f2();
        a.show();
        
    }

    //作为"形参"
    public static void f1(IA ia) {
        ia.show();
    }
    
    //作为"返回值"
    public static IA f2(){
        return () -> System.out.println("嘻嘻...");
    }
}

函数式接口作为形参时,必须要使用这个接口的实现子类来作为实参,而这个实现子类又必须要重写接口的抽象方法,所以就可以直接使用Lambda表达式作为实参传入(做返回值同样)

7、函数式编程-Lambda的应用-类库接口-Lambda作为形参和返回值

public class Demo {
    public static void main(String[] args) {
        //1.Lambda作为形参
        f1(()-> System.out.println("线程启动!"));
        //2.Lambda作为返回值
        Runnable r = f2();
        new Thread(r).start();
        

    }

    //使用Lambda作为"形参"
    public static void f1(Runnable runnable) {
        new Thread(runnable).start();
    }

    //使用Lambda作为"返回值"
    public static Runnable f2(){
        return () -> System.out.println("线程启动....");
    }
}

8、方法引用-使用自定义静态方法替代Lambda(“引用”理解为“替代”)

方法引用:就是使用已存在的方法替代Lambda表达式

@FunctionalInterface
interface IA{
    public void show();
}
public class Demo {
    public static void main(String[] args) {

       fun(Demo::method);//Demo::method代替:Lambda,Lambda代替:匿名内部类。

        fun(Demo::f2);//OK的--静态方法,必须通过"类名"引用,不能通过"对象名"引用。

        fun(Demo::f3);//错误的,因为其参数不同

    }

    public static void fun(IA ia) {
        ia.show();
    }

    //其它方法
    public static void method(){
        System.out.println("呵呵...");
    }

    private static void f2(){
        System.out.println("嘻嘻....");
    }

    public static void f3(String s) {
        System.out.println(s);
    }
}

9、方法引用-使用类库静态方法替代Lambda

@FunctionalInterface
interface IA{
    //打印一个int数组的所有元素
    public String printArray(int[] arr);
}
public class Demo {
    public static void main(String[] args) {
        int[] arr = {1432,432,432,4325,424,324,32,54,51,412,35,25,144,3};
        //使用匿名内部类
        fun(new IA(){
            @Override
            public String printArray(int[] arr) {
                StringBuilder bld = new StringBuilder("[");
                for (int i = 0; i < arr.length; i++) {
                    bld.append(arr[i]);
                    if (i < arr.length - 1) {
                        bld.append(" ,");
                    }else{
                        bld.append("]");
                    }
                }
               return bld.toString();
            }
        },arr);

        //使用Lambda
        fun((int[] array) -> {
            StringBuilder bld = new StringBuilder("[");
            for (int i = 0; i < array.length; i++) {
                bld.append(array[i]);
                if (i < array.length - 1) {
                    bld.append(" ,");
                } else {
                    bld.append("]");
                }
            }
            return bld.toString();
        }, arr);

        //使用Arrays的toString()方法来替代:Lambda
        fun(Arrays::toString, arr);
    }

    //定义方法,可以打印数组
    public static void fun(IA a, int[] arr) {
        System.out.println(a.printArray(arr));
    }
}

10、方法引用-替代原则

“替代的方法”的形参、返回值类型,必须和被替换的“函数式接口”中的抽象方法一致

11、方法引用-使用对象成员方法替代Lambda

@FunctionalInterface
interface Game{
    public void run();
}
class Student{
    public void playGame(Game game) {
        System.out.println("我开始打游戏:");
        game.run();
    }
}

class Teacher{
    public void like(){
        System.out.println("我喜欢喝茶(我是老师).....");
    }
}
public class Demo {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.playGame(()-> System.out.println("王者荣耀开始运行....."));
        stu.playGame(()-> System.out.println("我喜欢喝茶...."));

        //使用Teacher类的like()方法来代替Lambda表达式,打印:我喜欢喝茶....
        Teacher t = new Teacher();
        stu.playGame(t::like);//引用Teacher的like()方法。
	  //或者
        stu.playGame(new Teacher()::like);
    }
}

12、方法引用-使用super父类方法替代Lambda

@FunctionalInterface
interface Game{
    public void run();
}
class Fu{
    public void like(){
        System.out.println("我喜欢喝啤酒(我是父亲)....");
    }
}
class Student extends Fu{
    public void playGame(Game game) {
        System.out.println("我开始打游戏:");
        game.run();
    }

    public void show(){
	   //1.使用Lambda
        playGame(() -> System.out.println("我喜欢喝啤酒...."));
	   //2.使用父类的like方法代替Lambda表达式
        playGame(super::like);//使用父类的like方法代替Lambda表达式
    }

}
public class Demo {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.show();
    }
}

13、方法引用-使用this本类方法替代Lambda

@FunctionalInterface
interface Game{
    public void run();
}

class Student{
    public void playGame(Game game) {
        System.out.println("我开始打游戏:");
        game.run();
    }

    public void show(){
//        playGame(() -> System.out.println("我喜欢打羽毛球...."));
        playGame(this::ymq);
    }

    public void ymq(){
        System.out.println("我喜欢打羽毛球....");
    }
}
public class Demo {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.show();
    }
}

14、方法引用-类的构造器引用

1)、无参的构造方法

class Cat{
    public Cat(){
    }
    public void eat(){
        System.out.println("小猫吃鱼....");
    }
}

interface CatFactory{
    //生产Cat
    public Cat getCat();
}

public class Demo {
    public static void main(String[] args) {
        //调用fun
        //1.使用:匿名内部类
        fun(new CatFactory() {
            @Override
            public Cat getCat() {
                return new Cat();
            }
        });

        //2.使用Lambda表达式
        fun(()->{return new Cat();});

        //3.使用Cat的无参构造方法替代:getCat()方法
        fun(Cat::new);
    }

    public static void fun(CatFactory cf) {
        Cat c = cf.getCat();
        c.eat();
    }
}

2)、有参构造方法

class Cat{
    private String name;
    public Cat(){
    }
    public Cat(String name) {
        this.name = name;
    }

    public void eat(){
        System.out.println("我是一只 " + name + " 我爱吃鱼....");
    }
}

interface CatFactory{
    //生产Cat
    public Cat getCat(String name);
}

public class Demo {
    public static void main(String[] args) {
        //调用fun
        //1.使用:匿名内部类
        fun(new CatFactory() {
            @Override
            public Cat getCat(String name) {
                return new Cat(name);
            }
        },"机器猫");

        //2.使用Lambda表达式
        fun((String n)->{return new Cat(n);},"机器猫");

        //3.使用Cat的有参构造方法替代:getCat(String name)方法
        fun(Cat::new,"机器猫");
    }

    public static void fun(CatFactory cf,String name) {
        Cat c = cf.getCat(name);
        c.eat();
    }
}

15、方法引用-数组构造器引用

@FunctionalInterface
interface IA{
    public int[] getArr(int len);
}

public class Demo {
    public static void main(String[] args) {
        //2.使用Lambda
        fun((int len)->{return new int[len];},10);

        //3.使用数组的构造器代替:Lambda
        fun(int[]::new,15);
    }

    public static void fun(IA a,int len){
        int[] arr = a.getArr(len);
        System.out.println(arr.length);
    }
}

16、常用函数式接口-生产者接口-Supplier接口

生产者接口:只生产数据,不接收参数

public class Demo {
    public static void main(String[] args) {
        show(()->{return 10;});
        show2(()->{return "Hello";});
    }

    public static void show(Supplier<Integer> ia) {
        Integer n = ia.get();
        System.out.println(n);
    }

    public static void show2(Supplier<String> ia) {
        String s = ia.get();
        System.out.println(s);
    }
}

17、常用函数式接口-消费者接口-Consumer接口-抽象方法accept

消费者接口:只接收参数,无返回值

public class Demo {
    public static void main(String[] args) {
        //1.匿名内部类
        fun(new Consumer<String>() {
            @Override
            public void accept(String string) {
                System.out.println(string.toLowerCase());
            }
        }, "Hello");

        //2.使用Lambda
        fun((String s) -> System.out.println(s.toUpperCase()),"Hello");


    }

    public static void fun(Consumer<String> consumer,String s) {
        consumer.accept(s);
    }
}

18、常用函数式接口-Consumer接口-默认方法andThen

将俩个Consumer对象的accept()方法的结果连在一起

public static void main(String[] args) {
    fun((String s) -> System.out.println(s.toLowerCase()),
        (String s) -> System.out.println(s.toUpperCase()), "Hello");
}

public static void fun(Consumer<String> one, Consumer<String> two,String s) {
    one.andThen(two).accept(s);
}

复习

  • 能够使用@FunctionalInterface注解

    强制定义为函数式接口

  • 能够自定义无参无返回函数式接口

    @FunctionalInterface
    interface IA{
        public void show();
    }
    
  • 能够自定义有参有返回函数式接口

    @FunctionalInterface
    interface IA{
        public Srting show(String str1,String str2);
    }
    
  • 能够理解Lambda延迟执行的特点

    interface IA{
    	public String buildString();
    }
    public static void main(Stirng[] args){
    	String s1 = "...";
    	String s2 = "...";
    	String s3 = "...";
    	log(1,()->{return s1 + s2 + s3;});
    }
    public static void log(int level,IA msg){
    	if(level == 1){//只有当level = 1时,才调方法。
    		System.out.println(msg.buildString());
    	}
    }
    
  • 能够使用Lambda作为方法的参数

    main(){
        fun(()->System.out.println("线程开始运行"));
    }
    public static void fun(Runnable r){
    }
    
  • 能够使用Lambda作为方法的返回值

    main(){
        Runnable r = getRun();
        new Thread(r).start();
    }
    public static Runnable getRun(){
        return ()->System.out.println("线程开始运行");
    }
    
  • 能够使用输出语句的方法引用

    interface IA{
    	public void show(String s);
    }
    public static void main(String[] args){
    	//1.使用Lambda
    	fun((String s)->System.out.println(s),"Hello");
    
    	//2.使用System.out.println(String s)方法代替
    	fun(System.out::println,"Hello");
    }
    public sttaic void fun(IA a,String s){
    	a.show(s);
    }
    
  • 能够通过4种方式使用方法引用

    静态方法引用:

    interface IA{
    	public void printArray(int[] arr);
    }
    main(){
    	int[] arr = {22,4,32,33,14,32,4,234,324,32};
    	fun(Arrays::toString,arr);
    }
    public static void fun(IA a,int[] arr){
    	a.printArray(arr);
    }
    

    成员方法引用:

    interface Game{
    	public void run();
    }
    class Student{
    	public void playGame(Game g){
    		g.run();
    	}
    }
    class Teacher{
    	public void like(){
    		System.out.println("我喜欢喝茶...");
    	}
    }
    main(){
    	Student stu = new Student();
    	stu.playGame(()->System.out.println("我开始打游戏..."));
    	//使用其它类的成员方法代替:
    	Teacher t = new Teacher();
    	stu.playGame(t::like);
    }
    

    super引用:

    interface Game{
    	public void run();
    }
    class Fu{
    	public void like(){
    		System.out.println("我喜欢喝啤酒...");
    	}
    }
    class Student extends Fu{
    	public void playGame(Game g){
    		g.run();
    }
    	public void show(){
    		playGame(()->System.out.println("我喜欢喝啤酒...");
    		playGame(super::like);//引用父类的like方法
    	}
    }
    main(){
    	Student stu = new Student();
    	stu.show();
    }
    

    this引用:

    interface Game{
    	public void run();
    }
    class Student{
    	public void playGame(Game g){
    		g.run();
    	}
    	public void show(){
    		//使用Lambda
    		//	playGame(()->System.out.println("我喜欢泡妞...");
    		//使用字节的like()方法代替
    		playGame(this::like);
    	}
    	public void like(){
    		System.out.println("我喜欢泡妞...");
    	}
    }
    main(){
    	Student stu = new Student();
    	stu.show();
    }
    
  • 能够使用类和数组的构造器引用

    无参的构造方法:

    class Cat{
        public Cat(){
        }
        public void eat(){
            System.out.println("小猫吃鱼....");
        }
    }
    
    interface CatFactory{
        //生产Cat
        public Cat getCat();
    }
    
    public class Demo {
        public static void main(String[] args) {
            //调用fun
            //1.使用:匿名内部类
            fun(new CatFactory() {
                @Override
                public Cat getCat() {
                    return new Cat();
                }
            });
    
            //2.使用Lambda表达式
            fun(()->{return new Cat();});
    
            //3.使用Cat的无参构造方法替代:getCat()方法
            fun(Cat::new);
        }
    
        public static void fun(CatFactory cf) {
            Cat c = cf.getCat();
            c.eat();
        }
    }
    

    有参构造方法:

    class Cat{
        private String name;
        public Cat(){
        }
        public Cat(String name) {
            this.name = name;
        }
    
        public void eat(){
            System.out.println("我是一只 " + name + " 我爱吃鱼....");
        }
    }
    
    interface CatFactory{
        //生产Cat
        public Cat getCat(String name);
    }
    
    public class Demo {
        public static void main(String[] args) {
            //调用fun
            //1.使用:匿名内部类
            fun(new CatFactory() {
                @Override
                public Cat getCat(String name) {
                    return new Cat(name);
                }
            },"机器猫");
    
            //2.使用Lambda表达式
            fun((String n)->{return new Cat(n);},"机器猫");
    
            //3.使用Cat的有参构造方法替代:getCat(String name)方法
            fun(Cat::new,"机器猫");
        }
    
        public static void fun(CatFactory cf,String name) {
            Cat c = cf.getCat(name);
            c.eat();
        }
    }
    数组构造器:
    @FunctionalInterface
    interface IA{
        public int[] getArr(int len);
    }
    
    public class Demo {
        public static void main(String[] args) {
            //2.使用Lambda
            fun((int len)->{return new int[len];},10);
    
            //3.使用数组的构造器代替:Lambda
            fun(int[]::new,15);
        }
    
        public static void fun(IA a,int len){
            int[] arr = a.getArr(len);
            System.out.println(arr.length);
        }
    }
    数组构造器:
    @FunctionalInterface
    interface IA{
        public int[] getArr(int len);
    }
    
    public class Demo {
        public static void main(String[] args) {
            //2.使用Lambda
            fun((int len)->{return new int[len];},10);
    
            //3.使用数组的构造器代替:Lambda
            fun(int[]::new,15);
        }
    
        public static void fun(IA a,int len){
            int[] arr = a.getArr(len);
            System.out.println(arr.length);
        }
    }
    数组构造器:
    @FunctionalInterface
    interface IA{
        public int[] getArr(int len);
    }
    
    public class Demo {
        public static void main(String[] args) {
            //2.使用Lambda
            fun((int len)->{return new int[len];},10);
    
            //3.使用数组的构造器代替:Lambda
            fun(int[]::new,15);
        }
    
        public static void fun(IA a,int len){
            int[] arr = a.getArr(len);
            System.out.println(arr.length);
        }
    }
    数组构造器:
    @FunctionalInterface
    interface IA{
        public int[] getArr(int len);
    }
    
    public class Demo {
        public static void main(String[] args) {
            //2.使用Lambda
            fun((int len)->{return new int[len];},10);
    
            //3.使用数组的构造器代替:Lambda
            fun(int[]::new,15);
        }
    
        public static void fun(IA a,int len){
            int[] arr = a.getArr(len);
            System.out.println(arr.length);
        }
    }
    数组构造器:
    @FunctionalInterface
    interface IA{
        public int[] getArr(int len);
    }
    
    public class Demo {
        public static void main(String[] args) {
            //2.使用Lambda
            fun((int len)->{return new int[len];},10);
    
            //3.使用数组的构造器代替:Lambda
            fun(int[]::new,15);
        }
    
        public static void fun(IA a,int len){
            int[] arr = a.getArr(len);
            System.out.println(arr.length);
        }
    }
    数组构造器:
    @FunctionalInterface
    interface IA{
        public int[] getArr(int len);
    }
    
    public class Demo {
        public static void main(String[] args) {
            //2.使用Lambda
            fun((int len)->{return new int[len];},10);
    
            //3.使用数组的构造器代替:Lambda
            fun(int[]::new,15);
        }
    
        public static void fun(IA a,int len){
            int[] arr = a.getArr(len);
            System.out.println(arr.length);
        }
    }
    数组构造器:
    @FunctionalInterface
    interface IA{
        public int[] getArr(int len);
    }
    
    public class Demo {
        public static void main(String[] args) {
            //2.使用Lambda
            fun((int len)->{return new int[len];},10);
    
            //3.使用数组的构造器代替:Lambda
            fun(int[]::new,15);
        }
    
        public static void fun(IA a,int len){
            int[] arr = a.getArr(len);
            System.out.println(arr.length);
        }
    }
    //数组构造器:
    @FunctionalInterface
    interface IA{
        public int[] getArr(int len);
    }
    
    public class Demo {
        public static void main(String[] args) {
            //2.使用Lambda
            fun((int len)->{return new int[len];},10);
    
            //3.使用数组的构造器代替:Lambda
            fun(int[]::new,15);
        }
    
        public static void fun(IA a,int len){
            int[] arr = a.getArr(len);
            System.out.println(arr.length);
        }
    }
    
  • 能够使用Supplier函数式接口

    生产者:

    @FunctionalInterface
    public interface Supplier<T> {
    
            T get();
    }
    

    使用:

    public static void main(String[] args) {
        show(()->{return 10;});
        show2(()->{return "Hello";});
    }
    
    public static void show(Supplier<Integer> ia) {
        Integer n = ia.get();
        System.out.println(n);
    }
    
    public static void show2(Supplier<String> ia) {
        String s = ia.get();
        System.out.println(s);
    }
    
  • 能够使用Consumer函数式接口

    消费者接口:

    @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); };
        }
    }
    

    使用:

    public static void main(String[] args) {
        //2.使用Lambda
        fun((String s) -> System.out.println(s.toUpperCase()),"Hello");
    }
    
    public static void fun(Consumer<String> consumer,String s) {
        consumer.accept(s);
    }
    
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值