概念
如果说一个接口内有且只有一个方法,而且该方法是一个缺省属性为public abstract方法,那么该接口可以称之为函数式接口
有自定义函数式接口,还有系统中提供的函数式接口,例如:Comparator<T> 、 Runnable
可以直接利用JDK1.8的新特征,Lambda来使用。
Lambda表达式对比匿名内部类使用:
1.简化了代码接口
2.节约了内存资源
3.让程序员更加关注“我要做什么”,而不是“为了做什么而完成什么”
@FunctionalInterface使用
类似于 @Override,开启代码重写格式严格检查
格式:
/**
* 使用FunctionalInterface检查函数式接口格式问题
* 要求当前接口中有且只有一个缺省属性为public abstract的方法
* @Author kk
* @Date 2020/3/11 9:56
*/
@FunctionalInterface
public interface FunctionalType {
void test();
}
代码中使用函数式接口
1.让程序的目的性更强
2.提供复用,普适性的价值
3.节约资源
函数式编程思想
Lambda延迟执行
日志记录
日志是否保存会存在等级限制;演示一个根据不同等级来记录log日志
要求:
等级==1 记录log日志,其他情况不记录
使用函数式接口提供日志信息功能
这里需要一个函数式接口,返回值类型是String类型,其他的无所谓
Lambda作为方法参数和返回值
参数演示:
Runnbale接口
package com.wcc.b_Lambda;
/**
* Runnable接口函数式接口使用,作为方法的参数
* @Author kk
* @Date 2020/3/11 11:18
*/
public class Demo3 {
public static void main(String[] args) {
//匿名内部类,完成对应当前Runnable接口实现类对象使用,作为Thread构造方法参数
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("现成代码");
}
}).start();
//Lambda直接作为方法的参数
Thread thread = new Thread(() -> System.out.println("线程执行"), "线程");
thread.start();
}
}
Java中提供过的比较接口Comparator<T>,利用一些返回值作为方法中操作的调节
public interface Comparator<T>{
int compare<T o1, T o2>
}
package com.wcc.b_Lambda;
import java.util.Arrays;
import java.util.Comparator;
/**
* Lambda完成函数式接口,利用返回值作为其他操作返回的数据
* @Author kk
* @Date 2020/3/11 11:25
*/
public class Demo4 {
public static void main(String[] args) {
/*
字符串排序,默认是一个字典顺序
*/
String[] arr = {"a", "cccccccccccccccc", "bb", "dddd"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
//利用一个函数式接口完成的方法,利用方法的返回值作为当前sort方法运行
//所需参数,该参数用于比较规则约束
Arrays.sort(arr,stringComparator());
System.out.println(Arrays.toString(arr));
Arrays.sort(arr, Comparator.comparingInt(String::length));
/*
Comparator:接口
comparingInt:按照int类型方式比较判断
String:表示比较的类型是String类型,比较什么类型用什么类型
length:按照String类型的哪一种方式比较
*/
System.out.println(Arrays.toString(arr));
}
/**
* 按照字符串长度来排序,返回值类型是一个Comparator<String>接口
* 这里需要完成Comparator接口中的compara方法
*
* @return 已经完成方法体的Comparator接口,并且数据类型是String类型
*/
public static Comparator<String> stringComparator(){
return (a, b) -> a.length() - b.length();
}
}
Java中提供的常用函数式接口
JDK常用函数式接口概述
java.util.function包名,提供了很多函数式接口;规范了一些操作,提升了开发效率,更加专注于目的性
Supplier<T>生产者,返回一个指定类型的数据
Consumer<T>消费者,小号一个指定类型的数据
Predicate<T>判断条件,过滤使用
Function<T,R>类型转换
Supplier<T>生产者,返回一个指定类型的数据
java.util.function.Supplier<T>
有且只有一个方法
T get();
不需要参数,返回指定T类型数据
package com.wcc.b_Lambda;
import java.util.function.Supplier;
/**
* Supplier函数式接口演示
* @Author kk
* @Date 2020/3/11 10:53
*/
public class Demo2 {
public static void main(String[] args) {
String msg1 = "异常位置XXXX";
String msg2 = "异常问题XXXX";
String msg3 = "异常时间XXXX";
//这里需要的是一个函数式接口,直接传入一个lambda表达式
log(Level.HIGH,() -> {
System.out.println("Lambda表达式执行!");
return msg1 + msg2 + msg3;
});
/*
Lambda表达式优化
*/
log(Level.HIGH,() -> msg1 + msg2 + msg3);
}
/**
* 根据日志等级Level来确定是否需要记录日志
* @param level Level枚举类型,有三个数据 HIGH,MID,LOW
* @param supplier Supplier函数式接口,利用T get()完成提供数据操作
*/
public static void log(Level level, Supplier<String> supplier){
/*
Supplier函数式接口利用get方法,提供对应的返回指定String类型数据的操作
*/
if(Level.HIGH == level){
//通过函数式接口获取调用对应的returnLogMessage()方法
System.out.println(supplier.get());
}
}
}
Consumer<T>消费者,小号一个指定类型的数据
Consumer<T>
操作使用的方法式
void accept(T t);
根据接口指定的数据类型接收对应数据,进行处理和消费,对外没有任何的返回
至于处理的过程:展示,处理,计算...跟你没关系
package com.wcc.d_consumer;
import java.util.function.Consumer;
/**
* 使用Consumer接口处理数据
* @Author kk
* @Date 2020/3/11 15:24
*/
public class Demo1 {
public static void main(String[] args) {
//该方法需要的参数是一个String类型,同时使用Consumer接口处理数据
//因为Consumer接口是一个函数式接口,可以使用Lambda表达式
testConsumer("烧花鸭,烧子鹅,烧雏鸡",(String str) -> {
String[] split = str.split(",");
for(String s : split){
System.out.println(s);
}
});
}
/**
* 给予当前方法一个String类型,通过Consumer函数式接口中的accept方法完成
* 对应字符串处理
* @param str String类型字符串
* @param consumer 我们要处理数据的函数式接口
*/
public static void testConsumer(String str, Consumer<String> consumer){
consumer.accept(str);
}
}
Predicate<T>判断条件是否合适,返回true/false,过滤使用
Predicate<T>一般用于调节判断,过滤数据的方法
函数式接口中指定的方法:
boolean test(T t);
处理T类型数据,返回boolean类型
and 与
or 或
negate 非
package com.wcc.e_predicate;
import java.util.function.Predicate;
/**
* 演示Predicate<T>基本使用
* boolean test(T t)
* @Author kk
* @Date 2020/3/11 16:12
*/
public class Demo1 {
public static void main(String[] args) {
boolean b = testPredicate("奥里给!!!", (str) -> {
return str.contains("给给!");
});
System.out.println("ret: " + b);
/*
优化Lambda表达式
*/
boolean b1 = testPredicate("给给给!", str -> str.contains("给给给!"));
System.out.println(b1);
}
/**
* 使用Predicate函数式接口利用boolean test(T t)对于当前数据进行判断操作,
* 返回boolean类型数据
*
* @param str 需要进行判断数据的String类型字符串
* @param pre 处理使用Predicate函数式接口
* @return 判断接口是否满足要求
*/
public static boolean testPredicate(String str, Predicate<String> pre) {
return pre.test(str);
}
}
Function<T,R>类型转换
使用R apply(T t)
转换只当类型T到R
package com.wcc.f_function;
import java.util.function.Function;
/**
* Function<T R>函数式接口
* R apply(T)
* @Author kk
* @Date 2020/3/11 16:50
*/
public class Demo1 {
public static void main(String[] args) {
String change = change(10, i -> i + "");
System.out.println(change);
}
/**
* 转换格式的方法,要求数据从Integer类型转换到指定的String类型
* @param i 需要转换的Integer类型
* @param fun 转换使用的Function函数式接口
* @return 返回值是String类型
*/
public static String change(Integer i, Function<Integer, String> fun){
return fun.apply(i);
}
}