• Java学习笔记43——函数式接口


    函数式接口

    函数式接口概述

    有且仅有一个抽象方法的接口
    是lambda表达式的前提

    需要注意的是

    • 默认方法不是抽象方法,因为它们已经实现了。
    • 重写了超类Object类中任意一个public方法的方法并不算接口中的抽象方法。

    Java中的函数式编程体现的就是Lambda表达式,所以函数式接口就是可以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,Java中的lambda才能顺利地进行推导

    public interface MyInterface{
    	void show();
    }
    
    • 1
    • 2
    • 3
    public class MyInterfaceDemo{
    	public static void main(String[] args){
    		MyInterface my=()->System.out.println("函数式接口");
    		my.show();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如何检测一个接口是不是函数式接口?

    • @FunctionalInterface
    • 放在接口定义的上方:如果是函数式接口编译通过,不是则编译失败

    注意

    • 自己定义函数式接口的时候,**@FunctionalInterface**是可选的,只要满足函数式接口的条件,不写也是,但是建议加上这个注解。

    函数式接口作为方法的参数

    需求

    • 定义一个类(RunnableDemo),在类中提供两个方法
      • 一个方法是:startThread(Runnable r) 方法参数Runnable是一个函数式接口
      • 一个方法是主方法,在主方法中调用startThread方法
    public class RunnableDemo{
    	public static void main(String[] args){
    		  //匿名内部类的方式
    		  startThread(new Runnable(){
    			@Override
    			public void run(){
    				System.out.println(Thread.currentThread().getName()+"线程启动了!");
    			}
    		});
    
    		//Lambda表达式改进
    		startThread(()->System.out.println(Thread.currentThread().getName()+"线程启动了!"));
    	}
    	private static void startThread(Runnable r){
    		//Thread t=new Thread(r);
    		//t.start();
    		new Thread(r).start();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    如果方法的参数是一个函数式接口,可以使用Lambda表达式作为参数传递

    • startThread(()->System.out.println(Thread.currentThread().getName()+“线程启动了!”));

    函数式接口作为方法的返回值

    需求

    • 定义一个类(ComparatorDemo)在类中提供两个方法
      • 一个方法是:ComparatorgetComparator() 方法的返回值是Comparator是一个函数式接口
      • 一个方法是主方法,在主方法中 调用getComparator方法
    public class ComparatorDemo{
    	public static void main(String[] args){
    		//构造使用场景
    		//定义集合存储字符串元素
    		ArrayList<String> array=new ArrayList<String> ();
    		array.add("c");
    		array.add("aaa");
    		array.add("bb");
    		System.out.println("排序前:"+array);
    		Collections.sort(array, getcomparator())  ;
    		System.out.println("排序后:"+array);
    	}
    	public static Comparator<String> getComparator(){
    		//匿名内部类的方式实现
    //		Comparator comp=new Comparator(){
    //			@Override
    //			public int compare(String s1,String s2){
    //				return 	s1.length()-s2.length();
    //			}
    //		};
    //		return comp;
    
    //		return new Comparator(){
    //			@Override
    //			public int compare(String s1,String s2){
    //				return  s1.length()-s2.length();
    //			}
    		//lambda表达式
    //		return (String s1,String s2)->{
    //			return s1.length()-s2.length();
    //			};
    //		}
    
    		return (s1,s2)-> return s1.length()-s2.length();
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    如果方法的返回值是一个函数式接口,可以使用lambda表达式作为结果返回

    常用的函数式接口

    Supplier接口

    Supplier:包含一个无参的方法

    • T get():获得结果
    • 该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据
    • supplier接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类
      型的数据供我们使用
    public class SupplierDemo{
    	public static void main(String[] args){
    //		String s=getString(()->{
    //			return "伦伦";
    //		});
    		String s=getString(()->"伦伦");
    		System.out.println(s);
    		Integer i=getInteger(()->30);
    		System.out.println(i);
    	}
    	//定义一个方法,返回一个字符串数据
    	private static String getString(Supplier<String> sup){
    		return sup.get();
    		
    	}
    	//定义一个方法返回整数数据
    	private static Integer getInteger(Supplier<Integer> sup){
    		return sup.get();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    Comsumer接口

    Consumer:包含两个方法

    • void accept(T t):对给定的参数执行此操作
    • default Consumer andThen(Consumer after): 返回一个组合的Consumer,依次执行此操作,然后执行after操作
    public class ConsumerDemo{
    	public static void main(String[] args){
    //		operatorString("伦伦",(String s)->{
    //			System.out.println(s);
    //		});
    		
    		operatorString("伦伦",s->System.out.println(s));
    		//方法引用改进
    		operatorString("伦伦",System.out::println);
    
    		operatorString("Y伦伦",(s)->{
    			System.out.println(new StringBuilder(s).reverse().toString());
    		});
    
    		//优化
    		operatorString("Y伦伦",s->System.out.println(new StringBuilder(s).reverse().toString()));
    		System.out.println("----------");
    		operatorString("Y伦伦",s->System.out.println(s),s->System.out.println(new StringBuilder(s).reverse().toString()));
    	}
    	//定义一个方法消费字符串数据
    	private static void operatorString(String name,Consumer<String> con){
    		con.accept(name);
    	}
    
    	//定义一个方法,用不同的方式消耗同一个字符串两次
    	private static void operatorString(String name,Consumer<String> con1,Consumer<String> con2){
    //		con1.accept(name);
    //		coo2.accept(name);
    		//改进
    		con1.andThen(con2).accept(name);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    Predicate接口

    Predicate:常用的四个方法

    • boolean test(T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
    • default Predicatenegate(): 返回一个逻辑的否定,对应逻辑非
    • defaultPredicateand(Predicateother): 返回一个组合判断,对应短路与
    • default Predicate or(Predicate other): 返回一个组合判断,对应短路或
    • Predicate接口通常用于判断参数是否满足指定的条件
    public class PredicateDemo01{
    	public static main(String[] args){
    		boolean b1=checkString("Hello",s->return s.length()>8);
    		System.out.println(b1);
    		boolean b2=checkString("HelloWorld",s->return s.length()>8);
    		System.out.println(b2);
    	}
    	private static boolean checkString(String s,Predicate<String> pre){
    		return pre.test(); 
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Function接口

    Function:常用的两个方法

    • R apply(T t):将此函数应用于给定的参数
    • default Function andThen(Function after): 返回一个组合数,首先将该函数应用于输入,然后将after函数应用于结果
    • Function接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值
    class FunctionDemo{
    	public static main(String[] args){
    		String s="伦伦,25";
    		covert(s,ss->{ss.split(",")[1]},ss->Integer::parseInt,i->i+100);
    	}
    	private static void covert(String s,Function<String,String> fun1,Function<String ,Integer> fun2,Function<Integer,Integer> fun3){
    		int i=fun1.abdThen(fun2).andThen(fun3).apply(s);
    		System.out.println(i);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    MyBatis介绍
    fcitx5 中文输入在 chrome/vscode 等应用中的问题及解决
    SpringBoot+Redis实现接口幂等性,就看这篇了
    【数据结构】数组和字符串(二):特殊矩阵的压缩存储:对角矩阵——一维数组
    计算机与软件技术系毕业设计(论文)实施意见-计算机毕业设计论文怎么写
    TensorFlow自定义训练函数
    强化学习学习笔记
    Python中的多态和封装是如何实现的
    直流有刷电机及Matlab/Simulink驱动仿真
    分类预测 | Matlab实现CNN-LSTM-SAM-Attention卷积长短期记忆神经网络融合空间注意力机制的数据分类预测
  • 原文地址:https://blog.csdn.net/Lz0113/article/details/134382266