函数式接口
如果说一个接口内有且只有一个方法,而且该方法是一个缺省属
性为public abstract方法,该接口可以称之为是一个函数式接口。
Comparator Runnable
@FunctionalInterface 使用,检查函数式接口格式问题。
要求当前接口中有且只有一个缺省属性为public abstract 的方法。
代码中使用函数式接口
1. 让程序的目的性更强。
2. 提供复用,普适性的价值。
3. 节约资源。
函数式编程思想
Lambda延迟执行
日志记录是否保存存在等级限制
package com.qfedu.b_lambda;
/**
* 日志等级记录操作
*
* @author Anonymous 2020/3/11 19:11
*/
public class Demo1 {
public static void main(String[] args) {
/*
这里存问题:
MIDDLE,LOWER是没有必要进行字符串累加,存在资源浪费问题。
字符串的累加过程,需要经过Level判断之后才可以执行,避免没有必要的性能浪费。
这里就可以使用Lambda表达式执行的延迟性,在没有满足level情况下,不去做字符串累加
过程。这里需要函数式接口
*/
log(Level.MIDDLE, "异常位置XXX," + "异常问题XXX," + "异常时间XXX");
}
/**
* 判断等级,是否需要记录当前日志信息
*
* @param level 枚举类型
* @param logMsg 需要记录的日志信息
*/
public static void log(Level level, String logMsg) {
// 判断是否满Level.HIGH要求
if (Level.HIGH == level) {
System.err.println(logMsg);
}
}
}
使用函数式接口提供日志信息功能
这里需要函数式接口,返回值类型是String类型
package com.qfedu.b_lambda;
/**
* 返回值为String类型方法的函数式接口
*
* @author Anonymous 2020/3/11 19:45
*/
@FunctionalInterface
public interface LogMessage {
String returnLogMessage();
}
package com.qfedu.b_lambda;
/**
* 使用函数式接口完成Log日志记录问题
*
* @author Anonymous 2020/3/11 19:47
*/
public class Demo2 {
public static void main(String[] args) {
String msg1 = "异常位置XXX";
String msg2 = "异常问题XXX";
String msg3 = "异常时间XXX";
log(Level.HIGH, () -> {
System.out.println("Lambda表达式执行!!!");
return msg1 + msg2 + msg3;
});
}
/**
* 根据日志等级Level来确定是否需要记录日志
*
* @param level 枚举类型,数据为 HIGH MIDDLE LOWER
* @param lm LogMessage函数式接口做方法的参数
*/
public static void log(Level level, LogMessage lm) {
if (Level.HIGH == level) {
// 通过函数式接口获取调用对应的returnLogMessage()方法
System.err.println(lm.returnLogMessage());
}
}
}
Lambda作为方法参数和返回值
匿名内部类来完成对应当前Runnable接口实现类对象使用,作为Thread构造方法参数。
new Thread(new Runnable() {
@Override
//执行目标
public void run() {
System.out.println("线程代码");
}
}).start();
Lambda表达式直接作为方法的参数。
Thread thread = new Thread(() -> {
System.out.println("线程执行的时间");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程执行");
}
, "线程");
thread.start();
Java中提供的比较接口Comparator
利用一些返回值作为方法中操作的条件
public interface Comparator<T> {
int compare(T o1, T o2);
}
package com.qfedu.b_lambda;
import java.util.Arrays;
import java.util.Comparator;
/**
* Lambda表示完成函数式接口,利用返回值作为其他操作所需的数据
*
* @author Anonymous 2020/3/11 20:11
*/
public class Demo4 {
public static void main(String[] args) {
/*
排序默认字典顺序
*/
String[] arr = {"3eeeeeeee", "2a","dddd", "1bb", "ccccccc", "3fffff"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
System.out.println("-------------------");
// 利用函数式接口完成的方法,利用方法的返回值作为当前sort方法运行
// 所需参数,该参数用于比较规则约束
Arrays.sort(arr, stringComparator());
System.out.println(Arrays.toString(arr));
System.out.println("--------------------");
Arrays.sort(arr, (a, b) -> a.length() - b.length());
System.out.println(Arrays.toString(arr));
Arrays.sort(arr, Comparator.comparingInt(String::length));
System.out.println(Arrays.toString(arr));
}
/**
* 按照字符串长度排序,返回值类型是Comparator<String>接口
* 这里需要完成Comparator接口中的compare方法
*
* @return 已经完成方法体的Comparator接口,并且数据类型是String类型
*/
public static Comparator<String> stringComparator() {
return (a, b) -> a.length() - b.length();
}
}
Java中提供的常用函数式接口
Supplier 生产者, 返回一个指定类型的数据。
java.util.function.Supplier
有且只有一个方法
T get(); 不需要参数,返回指定T类型数据
package com.qfedu.c_supplier;
import com.qfedu.b_lambda.Level;
import java.util.function.Supplier;
/**
* Supplier演示
*
* @author Anonymous 2020/3/11 20:24
*/
public class Demo1 {
public static void main(String[] args) {
String msg1 = "异常位置XXX";
String msg2 = "异常问题XXX";
String msg3 = "异常时间XXX";
log(Level.HIGH, () -> msg1 + msg2 + msg3);
}
/**
* 根据日志等级Level来确定是否需要记录日志
*
* @param level Level枚举类型,有三个数据 HIGH MIDDLE LOWER
* @param supplier Supplier函数式接口,利用T get() 完成提供数据操作
*/
public static void log(Level level, Supplier<String> supplier) {
/*
利用get方法,提供对应的返回指定String类型数据
*/
if (Level.HIGH == level) {
// 通过函数式接口获取调用对应的returnLogMessage()方法
System.err.println(supplier.get());
}
}
}
Consumer<T> 消费者, 消耗一个指定类型的数据。
Consumer<T>
操作使用的方式是 void accept(T t);
根据接口指定的数据类型接收对应数据,进行
处理和消费,对外没有任何的返回。
package com.qfedu.d_consumer;
import java.util.function.Consumer;
/**
* Consumer处理数据
*
* @author Anonymous 2020/3/11 20:33
*/
public class Demo1 {
public static void main(String[] args) {
// 该方法需要的参数是一个String类型,同时使用Consumer接口处理数据
// 因为Consumer接口是一个函数式接口,可以使用Lambda表达式
testConsumer("你,我,他", (string) -> {
String[] split = string.split(",");
for (String s : split) {
System.out.print(s);
}
});
}
/**
* 给予一个String类型,通过Consumer函数式接口中的accept方法完成对应字符串处理
*
* @param string String类型字符串
* @param consumer Consumer处理数据的函数式接口
*/
public static void testConsumer(String string, Consumer<String> consumer) {
consumer.accept(string);
}
}
Predicate 判断调节,过滤使用。
Predicate一般用于调节判断,过滤数据的方法。
函数式接口中指定的方法
boolean test(T t);
处理T类型数据,返回boolean true / false
package com.qfedu.e_predicate;
import java.util.function.Predicate;
/**
* Predicate<T>使用
*
* @author Anonymous 2020/3/11 20:42
*/
public class Demo1 {
public static void main(String[] args) {
// Predicate函数式接口,使用Lambda表达式作为方法的参数
boolean b = testPredicate("中国加油!!!",
(str) -> {
return str.contains("加油");
});
System.out.println(b);
/*
优化Lambda表达式,
*/
testPredicate("中国加油!!!", str -> str.contains("加油"));
}
/**
* 使用Predicate函数式接口利用boolean test(T t)对于当前数据进行判断
*
* @param str String类型字符串
* @param pre 处理使用Predicate函数式接口
* @return 判断接口是否满足要求,满足返回true,不满足返回false
*/
public static boolean testPredicate(String str, Predicate<String> pre) {
return pre.test(str);
}
}
Function<T,R> 类型转换,根据你指定的类型T, 转
换成对应类型R。
使用R apply(T t) 转换指定类型T到R。
package com.qfedu.f_function;
import com.qfedu.c_supplier.Person;
import java.util.function.Function;
/**
* Function<T, R> 函数式接口
* R apply(T)
*
* @author Anonymous 2020/3/11 20:51
*/
public class Demo1 {
public static void main(String[] args) {
// 数字转字符串
String change = change(10, i -> i + "");
System.out.println(change);
// 利用函数式接口处理一个String类型,转换成对应的Person类型
Person person1 = change("1,骚磊,16", str -> {
//解析字符串
String[] split = str.split(",");
Person person = new Person();
person.setId(Integer.parseInt(split[0]));
person.setName(split[1]);
person.setAge(Integer.parseInt(split[2]));
return person;
});
System.out.println(person1);
}
/**
* 目标数据从Integer类型转换到指定数据String类型
*
* @param i 目标数据Integer类型
* @param fun 转换使用的Function函数式接口
* @return 返回值的是String类型
*/
public static String change(Integer i, Function<Integer, String> fun) {
return fun.apply(i);
}
public static Person change(String str, Function<String, Person> fun) {
return fun.apply(str);
}
}