Lambda表达式使用的前提,就是接口必须是一个函数式接口
如果在接口中,只有一个抽象方法,那么这个接口就是函数式接口
3.格式说明:
使用注解来检查当前接口是否是一个函数式接口
@FunctionalInterface
如果不是函数式接口,则编译报错
4.作用:
想表达的是一个方法的内容,由于方法不在任何类中,所以称为函数
接口其实想表达的就是一个函数的声明
将来使用这个接口的实现类对象,来表达一个函数的实现
Java中不支持将函数作为一个数据,也就不能将这个函数进行各种传递,也就不能作为对象的成员变量存在
package com.cc.function_interface;
/*函数和方法的区别
* 函数:函数可以独立存在,不存在任何类中,(C语言中,没有对象和类的概念),Java中不支持,函数独立存在,需要进行包装
* 方法:是存在一个类中
* Lambda表达式使用的前提,就是接口必须是一个函数式接口
* 如果在接口中只有一个抽象方法,那么这个接口就是函数式接口
*
* */
public class Demo01 {
public static void main(String[] args) {
F2 f = get();
}
public static F2 get() {
F2 f = ()->System.out.println("666");
return f;
}
}
//不是函数式接口,加上注解会报错
//@FunctionalInterface
interface F1{
}
//通过注解可以判断是否是一个函数式接口
@FunctionalInterface
interface F2{
void run();
}
//有两个方法的也不是函数式接口,加上注解也会报错
//@FunctionalInterface
interface F3{
void method01();
void method02();
}
1、说明:
Java8中提供了一些常用的函数式接口,在使用类似功能的时候,不需要额外定义接口,直接使用jdk中提供的即可
2、罗列:
①Consumer
void accept(T t);
② Supplier
T get();
③Function
R apply(T t);
④Predicate
boolean test(T t)
当某个函数可以接收一个数据,并且处理这个数据,处理完成之后,不需要返回任何数据,这个函数需要当做数据来进行传递,就使用消费型接口
package com.cc.function_interface;
import java.util.function.Consumer;
/*常用内置的函数式接口:
* Consumer:消费型接口 有参无返回值 可以接收数据,但不返回,该函数当做数据进行传递
* void accept(T t)
* Supplier:供给型接口 无参有返回值
* T get()
* Function:函数型接口 有参有返回值
* R apply(T t)
* Predicate:断言型接口 有参有返回值
* Boolean test(T t)*/
public class Demo02 {
public static void main(String[] args) {
Consumer con = x->System.out.println(x);
test(800,con,"买东西");
//方法的引用
test(500,System.out::println,"买东西");
}
public static void test(int money,Consumer con,String str) {
System.out.println("花了"+money+"块钱");
con.accept(str);
}
}
函数式接口 名称 = 对象名 :: 方法名称
函数式接口 名称 = 类名 :: 静态方法名
3作用:
把已经实现的方法,作为一个数据,作为一个引用,赋值给某个函数式接口的引用
可以把这个引用当做方法的返回值,也可以作为方法的实际参数进行传递
4.本质:
可以把任意一个方法,作为函数式接口的一个实现类对象
package com.cc.day19;
public class Demo02 {
public static void main(String[] args) {
test01();
test02();
}
public static void test01() {
Printer p = x->System.out.println(x);
p.print("小耳朵CC");
//println方法在System.out输出流中已经实现,可以直接使用
Printer p1 = System.out::println;
p1.print("方法的引用");
}
public static void test02() {
//需求:完成一个整数加1之后的平方,该功能TestDemo中已经实现
//通过对象名::方法名 直接引用即可
TestDemo t = new TestDemo();
PrintNum p = t::print;//方法名后面不要加小括号
p.print(7);
}
}
//自定义一个类:完成一个整数加1之后的平方
class TestDemo{
public void print(int x) {
x+=1;
System.out.println(x*x);
}
}
//函数式接口
interface PrintNum{
void print(int x);
}
//函数式接口
interface Printer{
public abstract void print(String str);
}
如果需要定义函数,可以生产一个需要的数据,这个函数需要当做数据来进行传递,那么就可以使用供给型接口。
以前我们只能传递数据,现在可以传递生产数据的方式
package com.cc.day19;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.Supplier;
// 返回一个集合,集合存放[30-80]之间的随机数
public class Demo03 {
public static void main(String[] args) {
Random r = new Random();
//自定义要传入什么样的数据
List list = getNum(10,()->r.nextInt(50)+30);
System.out.println(list);
}
//@param 集合中元素的个数,Supplier对象
public static List getNum(int n,Supplier sup){
//创建一个集合
List list = new ArrayList();
for(int i=0;i
如果需要定义一个函数,接收一个数据,将数据进行处理,完成之后,还能返回一个结果,就可以使用函数型接口
以前我们只能传递处理好之后的数据,或者将原始数据传入方法
现在可以传入原始数据,并且还可以传入处理方式
5.提供功能:
andThen(Function f):在调用者处理方式之后,再进行参数的处理方式处理
package com.cc.day19;
import java.util.function.Function;
public class Demo04 {
public static void main(String[] args) {
//将String类型转换为int类型
//Function fun = x->Integer.parseInt(x);
//方法的引用
Function fun = Integer::parseInt;
int sN = parse("20",fun);
System.out.println(sN);
//完成输入一个数,返回这个数*10的结果
Function fun1 =x->x*=10;
int result = method(10,fun1);
//完成输入一个字符串,首先将字符串类型转换为int类型,再讲int类型的数*10之后返回
System.out.println(result);
int i = method01("7",fun,fun1);
System.out.println(i);
}
//传入String类型返回Integer类型
public static int parse(String str,Function fun) {
return fun.apply(str);
}
//传入Integer类型返回Integer类型
public static int method(int i,Functionfun) {
return fun.apply(i);
}
//两个函数型接口:andThen前一个函数型接口的返回值类型,必须和它后面的函数型接口的传入的类型保持一致
public static int method01(String str,Function fun1,Function fun2) {
return fun1.andThen(fun2).apply(str);//fun1,的返回值类型必须与fun2的传入数据类型一致才可以使用andThen
}
}
如果需要定义一个函数,接收一个数据,判断数据是否合法,返回一个boolean结果,就可以使用断言型接口
以前我们只能传入处理好的数据,到方法中
将原始数据传入,将过滤的条件也传入
5.提供的功能:
Predicate and(Predicate pre):在调用者条件判断之后,再由参数条件判断,返回两个条件的都满足的判断对象
Predicate or(Predicate pre):返回两个条件任意一个满足的判断对象
Predicate negate():返回的是调用者判断条件的取反
package com.cc.day19;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class Demo05 {
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add(10);
al.add(-5);
al.add(-2);
al.add(17);
al.add(25);
al.add(6);
al.add(49);
al.add(30);
al.add(66);
al.add(0);
//筛选为偶数
ArrayList list = filt(al,x->x%2==0);
System.out.println(list);
//筛选小于0
List list1 = filt(al,x->x<0);
System.out.println(list1);
//筛选为偶数,(或者)并且小于0的
list = filtOr(al,x->x%2==0,x->x<0);
System.out.println(list);
}
public static ArrayList filt(ArrayList al,Predicate pre){
ArrayList list = new ArrayList();
for(Integer i:al) {
if(pre.test(i)) {
list.add(i);
}
}
return list;
}
public static ArrayList filtOr(ArrayList al,Predicate pre1,Predicate pre2){
ArrayList list = new ArrayList();
for(Integer i:al) {
//至少一个成立即可
//if(pre1.or(pre2).test(i)){
//and两个条件同时成立
if(pre1.and(pre2).test(i)){
list.add(i);
}
}
return list;
}
}