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

函数式接口

函数式接口

函数式接口概述

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

需要注意的是

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

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

java 复制代码
public interface MyInterface{
	void show();
}
java 复制代码
public class MyInterfaceDemo{
	public static void main(String[] args){
		MyInterface my=()->System.out.println("函数式接口");
		my.show();
	}
}

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

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

注意

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

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

需求

  • 定义一个类(RunnableDemo),在类中提供两个方法
    • 一个方法是:startThread(Runnable r) 方法参数Runnable是一个函数式接口
    • 一个方法是主方法,在主方法中调用startThread方法
java 复制代码
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();
	}
}

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

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

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

需求

  • 定义一个类(ComparatorDemo)在类中提供两个方法
    • 一个方法是:Comparator<String>getComparator() 方法的返回值是Comparator是一个函数式接口
    • 一个方法是主方法,在主方法中 调用getComparator方法
java 复制代码
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<String> comp=new Comparator<String>(){
//			@Override
//			public int compare(String s1,String s2){
//				return 	s1.length()-s2.length();
//			}
//		};
//		return comp;

//		return new Comparator<String>(){
//			@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();
		}
	}
}

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

常用的函数式接口

Supplier接口

Supplier:包含一个无参的方法

  • T get():获得结果
  • 该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据
  • supplier接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类
    型的数据供我们使用
java 复制代码
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();
	}
}

Comsumer接口

Consumer:包含两个方法

  • void accept(T t):对给定的参数执行此操作
  • default Consumer andThen(Consumer after): 返回一个组合的Consumer,依次执行此操作,然后执行after操作
java 复制代码
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);
	}
}

Predicate接口

Predicate:常用的四个方法

  • boolean test(T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
  • default Predicatenegate(): 返回一个逻辑的否定,对应逻辑非
  • defaultPredicateand(Predicateother): 返回一个组合判断,对应短路与
  • default Predicate or(Predicate other): 返回一个组合判断,对应短路或
  • Predicate接口通常用于判断参数是否满足指定的条件
java 复制代码
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(); 
	}
}

Function接口

Function<T,R>:常用的两个方法

  • R apply(T t):将此函数应用于给定的参数
  • default Function andThen(Function after): 返回一个组合数,首先将该函数应用于输入,然后将after函数应用于结果
  • Function<T,R>接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值
java 复制代码
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);
	}
}
相关推荐
用户0332126663679 分钟前
Java 查找并替换 Excel 中的数据:详细教程
java
间彧11 分钟前
ThreadLocal实现原理与应用实践
java
若水不如远方18 分钟前
Netty的四种零拷贝机制:深入原理与实战指南
java·netty
使一颗心免于哀伤18 分钟前
《设计模式之禅》笔记摘录 - 21.状态模式
笔记·设计模式
用户74936368484322 分钟前
【开箱即用】一分钟使用java对接海外大模型gpt等对话模型,实现打字机效果
java
SimonKing41 分钟前
一键开启!Spring Boot 的这些「魔法开关」@Enable*,你用对了吗?
java·后端·程序员
间彧1 小时前
Spring Boot集成Spring Security 6.x完整指南
java
xiezhr2 小时前
用户只需要知道「怎么办」,不需要知道「为什么炸了」
java·api·接口设计规范
xiezhr2 小时前
接口设计18条军规:写给那些半夜被“502”叫醒的人
java·api·restful
RainbowSea11 小时前
12. LangChain4j + 向量数据库操作详细说明
java·langchain·ai编程