(62)Java基础 --函数式接口

目录

一、概述

二、常用内置函数式接口

1、消费型接口

2、方法引用

3、供给型接口

4、函数型接口

5、断言型接口

6、其他接口介绍


一、概述

Lambda表达式使用的前提,就是接口必须是一个函数式接口。

定义

     如果在接口中,只有一个抽象方法,那么这个接口就是函数式接口。

格式

     使用注解来检查当前接口是否是一个函数式接口

     @FunctionalInterface

     如果不是函数式接口,则编译报错

作用

  想表达的是一个方法的内容,由于方法不在任何类中,所以称为函数

  接口其实想表达的就是一个函数的声明

  将来使用这个接口的实现类对象,来表达一个函数的实现

  Java中不支持将函数作为一个数据,也就不能将这个函数进行各种传递,也就不能作为对象的成员变量存在

  只能在方法外加一层接口的声明,将来可以传递方法所在接口的实现类对象,来间接的传递方法内容

ublic class Demo01_函数式接口 {
	
	public static void main(String[] args) {
		
		Inter1 i = new Inter1(){
			public void test1(){
				System.out.println("hello");
			}
		};
	}
	
	// Inter1的对象作为参数
	public static void method1(Inter1 i){
		i.test1();
	}
	
	//Inter1的对象作为返回值
	public static Inter1 method2(){
	   /*	
		Inter1 i = new Inter1(){
			public void test1(){
				System.out.println("hello");
			}
		};
		*/
		Inter1 i = ()->System.out.println("hello");
		return i;
	}
}

@FunctionalInterface
interface Inter1{
	void test1();
}

//@FunctionalInterface
interface Inter2{     // 没有方法
	
}

//@FunctionalInterface
interface Inter3{      // 有多个方法
	void test1();
	void test2();
}

二、常用内置函数式接口

Java8中提供了一些常用的函数式接口,在使用类似功能的时候,不需要额外定义接口,直接使用jdk中提供的即可。

函数式接口

参数类型

返回类型

说明

Consumer<T>

消费型接口

T

void

对类型为T的对象操作,

方法:void accept(T t)

Supplier<T>

供给型接口

T

返回类型为T的对象,

方法:T get();可用作工厂

Function<T, R>

函数型接口

T

R

对类型为T的对象操作,并返回结果是R类型的对象。

方法:R apply(T t);

Predicate<T>

断言型接口

T

boolean

判断类型为T的对象是否满足条件,并返回boolean 值。

方法boolean test(T t);

1、消费型接口

Consumer<T>

      抽象方法

            void accept(T t);

作用

       当某个函数可以接收一个数据,并且处理这个数据,处理完成之后,不需要返回任何数据,这个函数需要当做数据来进行传递,就使用消费型接口

public class Demo02_消费型接口_Consumer {
	
	public static void main(String[] args) {
	/*	
		Consumer<String> con = new Consumer<String>() {
			public void accept(String str){
				System.out.println(str);
			}
		};
		test(con,800,"买书");
		
		*/
		Consumer<String> con = (str)->System.out.println(str);
		test(con,800,"买书");
	}
	
	public static void test(Consumer<String> con,int money,String str){
		System.out.println("花了"+money+"块钱");
		con.accept(str);
	}

}

2、方法引用

写一个函数式接口时,方法的实现(lambda体),已经被某个其他的对象实现了,就不需要在Lambda体中,再次调用这个实现,而可以直接使用那个已经定义好的方法。

格式

  函数式接口 名称 = 对象名 :: 方法名称

  函数式接口 名称 = 类名 :: 静态方法名

作用

  把已经实现的方法,作为一个数据,作为一个引用,赋值给某个函数式接口的引用

  可以把这个引用当做方法的返回值,也可以作为方法的实际参数进行传递

本质

  可以把任意一个方法,作为函数式接口的一个实现类对象

public class Demo03_方法引用 {
	
	public static void main(String[] args) {
		//test1();
		test2();
	}
	
	public static void test2(){
		MyPrinterNum mp = (x)->{x=x+1;x=x*x;System.out.println(x);};
		mp.myPrint(5);
		
		TestDemo td = new TestDemo();
		MyPrinterNum mp2 = td::myMethod;
		mp2.myPrint(5);
		/*
		 * 将 TestDemo 中的 myMethod 传递给 MyPrinterNum 也就是传递给MyPrinterNum 的myPrint
		 * 也就是说myPrint 的实现就是TestDemo 中的myMethod的 方式
		 * */
		
	}
	
	public static void test1(){
		MyPrinter mp = (str)->System.out.println(str);
		mp.myPrint("hello");
		
		/*
		 * (str)->System.out.println(str); 就是在实现MyPrinter 的myPrint方法
		 * 而上面的这个实现的含义是:  把参数在控制台输出。
		 * 
		 * 把参数在控制台输出这个工作,在System.out类中 已经通过println方法实现过了
		 * 不用自己再使用Lambda表达式实现了,而可以直接引用System.out的println方法
		 * 
		 * */
		MyPrinter mp2 = System.out::println;
		mp2.myPrint("HELLO");
	}
}

class TestDemo{
	public void myMethod(int x){
		x = x+1;
		x = x*x;
		System.out.println(x);
	}
}

3、供给型接口

Supplier<T>

      抽象方法

            T get()

作用

  如果需要定义函数,可以生产一个需要的数据,这个函数需要当做数据来进行传递,那么就可以使用供给型接口。

  以前我们只能传递数据,现在可以传递生产数据的方式

public class Demo04_供给型接口_Supplier {
   /*
	 定义一个方法,返回一个集合,集合中n个满足要求的数据
	 
	 要求数据是随机数字,要在1-10之间
    * */
	
	public static void main(String[] args) {
		
		Supplier<Integer> sup = ()->{
			Random random = new Random();
			int num = random.nextInt(10)+1;
			return num;
		};
		
		List<Integer> list = getNum(5,sup);
		
		for(int x:list){
			System.out.println(x);
		}
		
	}
	
	public static List<Integer> getNum(int n,Supplier<Integer> sup){
		List<Integer> list = new ArrayList<Integer>();
		for(int i=1;i<=n;i++){
			list.add(sup.get());
		}
		return list;
	}
}

4、函数型接口

Function<T, R>

      抽象方法

            R apply(T t)

作用

  如果需要定义一个函数,接收一个数据,将数据进行处理,完成之后,还能返回一个结果,就可以使用函数型接口

  以前我们只能传递处理好之后的数据,或者将原始数据传入方法

  现在可以传入原始数据,并且还可以传入处理方式

提供功能

   andThen(Function f):在调用者处理方式之后,再进行参数的处理方式处理

public class Demo05_函数型接口 {
	/*
	 * 定义一个方法,传入一个String的变量, 把字符串转换成数字 并乘10后返回
	 * */
	public static void main(String[] args) {
/*		Function<String,Integer> fun = (str)->{
			int x = Integer.parseInt(str);
			x=x*10;
			return x;
		};
		*/
		Function<String,Integer> fun = (str)-> Integer.parseInt(str)*10;
		int result = method("10",fun);
		System.out.println(result);
	}
	/*
	 * str 是原数据 (要经过处理的数据)
	 * 
	 * fun 是处理方式
	 * */
	public static int method(String str,Function<String,Integer> fun){
		return fun.apply(str);
	}
}

使用andThen 增加处理方式

public class Demo06_函数型接口2 {
	/*
	 * 定义一个方法,传入一个String的变量, 把字符串转换成数字,并乘10,返回
	 * 
	 * 分开写的好处:更有利于代码的复用
	 * */	
	public static void main(String[] args) {
		                             //= (str)->Integer.parseInt(str);
		Function<String,Integer> fun1  = Integer::parseInt;
		Function<Integer,Integer> fun2 = (x)->x*10;

		int result = method("20",fun1,fun2);
		System.out.println(result);
	}
	
	public static int method(String str,Function<String,Integer> fun1,Function<Integer,Integer>fun2){
		return fun1.andThen(fun2).apply(str);
	}
}

5、断言型接口

Predicate<T>

      抽象方法

            boolean test(T t)

作用

   如果需要定义一个函数,接收一个数据,判断数据是否合法,返回一个boolean结果,就可以使用断言型接口

   以前我们只能传入处理好的数据,到方法中

   将原始数据传入,将过滤的条件也传入

提供的功能

   Predicate  and(Predicate pre):在调用者条件判断之后,再由参数条件判断,返回两个条件的都满足的判断对象

   Predicate  or(Predicate pre):返回两个条件任意一个满足的判断对象

   Predicate  negate():返回的是调用者判断条件的取反

public class Demo07_断言型接口_Predicate {

	public static void main(String[] args) {
		
		List<Integer> list = new ArrayList<Integer>();
		
		list.add(10);
		list.add(66);
		list.add(666);
		list.add(35);
		list.add(-20);
		list.add(0);
		list.add(33);
		
		List<Integer> list1 = filterEven(list,(x)-> x%2==0);
		System.out.println(list1);
		
		
		List<Integer> list2 = filterZheng(list1, (x)->x>0);
		System.out.println(list2);
		
		
		List<Integer> list3 = filterEvenAndZheng(list, (x)-> x%2==0, (x)->x>0);
		System.out.println(list3);
		
		List<Integer> list4 = filterEvenOrZheng(list, (x)-> x%2==0, (x)->x>0);
		System.out.println(list4);
		
		
		List<Integer> list5 = filterFu(list,(x)->x>=0);
		System.out.println(list5);
		
	}
	
	// 过滤list 留下偶数
	public static List<Integer> filterEven(List<Integer> list,Predicate<Integer> pre){  
		List<Integer> result = new ArrayList<Integer>();
		for(Integer x:list){
			if(pre.test(x)){
				result.add(x);
			}
		}
		return result;
	}
	
	// 过滤list,留下正数
	public static List<Integer> filterZheng(List<Integer> list,Predicate<Integer> pre){
		
		List<Integer> result = new ArrayList<Integer>();
		for(Integer x:list){
			if(pre.test(x)){
				result.add(x);
			}
		}
		return result;
	}
	
	// 使用and连接两个Predicate
	public static List<Integer> filterEvenAndZheng(List<Integer> list,Predicate<Integer> pre1,Predicate<Integer> pre2){
		List<Integer> result = new ArrayList<Integer>();
		
		for(Integer x:list){
			if(pre1.and(pre2).test(x)){
				result.add(x);
			}
		}
		return result;
	}
	
	//使用or连接两个Predicate
	public static List<Integer> filterEvenOrZheng(List<Integer> list,Predicate<Integer> pre1,Predicate<Integer> pre2){
		List<Integer> result = new ArrayList<Integer>();
		
		for(Integer x:list){
			if(pre1.or(pre2).test(x)){
				result.add(x);
			}
		}
		return result;
	}
	
	// 取反negate
	public static List<Integer> filterFu(List<Integer> list,Predicate<Integer> pre1){
		List<Integer> result = new ArrayList<Integer>();
		
		for(Integer x:list){
			if(pre1.negate().test(x)){
				result.add(x);
			}
		}
		return result;
	}
}

6、其他接口介绍

JDK提供了大量常用的函数式接口以丰富Lambda的典型使用场景,它们主要在java.util.function包中被提供

函数式接口

参数类型

返回类型

用途

BiFunction<T,U,R>

T,U

R

对类型为T,U参数应用操作,返回R类型的结果。

包含方法为Rapply(Tt,Uu);

UnaryOperator<T>

(Function子接口)

T

T

对类型为T的对象进行一元运算,并返回T类型的结果。

包含方法为Tapply(Tt);

BinaryOperator<T>

(BiFunction子接口)

T,T

T

对类型为T的对象进行二元运算,并返回T类型的结果。

包含方法为Tapply(Tt1,Tt2);

BiConsumer<T,U>

T,U

void

对类型为T,U参数应用操作。

包含方法为void accept(Tt,Uu)

ToIntFunction<T>

ToLongFunction<T>

ToDoubleFunction<T>

T

int

long

double

分别计算int、long、double、值的函数

IntFunction<R>

LongFunction<R>

DoubleFunction<R>

int

long

double

R

参数分别为int、long、double类型的函数

 

上一篇:(61)Java基础 --Lambda表达式

下一篇:(63)Java基础 --Stream API

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值