案例1:函数式接口作为参数
1. 1 原日志代码
public class Demo01Logger {
//只有日志等级为1时,才会打印日志信息
public static void showLog(int level, String massage){
if(level==1){
System.out.println(massage);
}
}
public static void main(String[] args) {
//定义三个日志信息
String msg1 = "hello";
String msg2 = "world";
String msg3 = "java";
showLog(1,msg1+msg2+msg3);
}
}
如代码所示,只有当level为1时,日志信息才会打印,但是当level为其他等级的时候,尽管不需要打印,但是日志信息已经完成拼接,此时会造成系统性能的浪费。
1.2 优化的代码
(1)函数式接口
/**
* 函数式接口:有且只有一个抽象方法的接口,称之为函数式接口
* 接口中可以包含其他方法,如:默认方法、静态方法、私有方法
*/
@FunctionalInterface //可以检测接口是否是一个函数式接口,不满足条件时编译失败
public interface messageBuilder {
public abstract String builderMessage();
}
(2)优化代码
public class Demo02Logger {
//只有日志等级为1时,才会打印日志信息
public static void showLog(int level, messageBuilder mb){
if(level==1){
System.out.println(mb.builderMessage());
}
}
public static void main(String[] args) {
//定义三个日志信息
String msg1 = "hello";
String msg2 = "world";
String msg3 = "java";
//messageBuilder是一个函数式接口,所以可以传递Lambda表达式
showLog(2,() -> {return msg1+msg2+msg3;});
/*
注意:Lambda表达式具有延迟加载的特性,当使用Lambda表达式将参数传递到对应的方法时,只有满足条件的情况下,才会对参数进行处理,不会存在性能的浪费
例如:当日志等级为1时,才会调用builderMessage()方法,才会进行字符串拼接
当日志等级不为1时,不会调用builderMessage()方法,也就不会进行字符串拼接
*/
}
}
案例2:函数式接口作为返回值
import java.util.Arrays;
import java.util.Comparator;
public class ComparatorDemo {
public static Comparator<String> getComparator(){
//使用匿名内部类的方式实现返回接口
/*return new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length()-o2.length();//按照字符串长度升序排列
}
};*/
//使用Lambda表达式实现
/*return (String o1, String o2)-> {
return o1.length()-o2.length();//按照字符串长度升序排列
};*/
//简化Lambda表达式
return (o1, o2) -> o1.length()-o2.length();
}
//调用
public static void main(String[] args) {
String[] strs = {"aaa","bbbs","c","dd"};
Arrays.sort(strs,getComparator());
System.out.println(Arrays.toString(strs));
}
}
实际开发中使用的

首先调用1,然后进入到具体的方法2中来,然后执行逻辑3,在到4,在调用4的时候执行apply方法的时候,跳转到5来,并且吧RedisClientFactory.getOrCreateClient(readUri)作为实参传入到5中的方法中来。