如果说一个接口内有且只有一个方法,而且该方法是一个缺省属性为public abstract方法,该接口可以称之为是一个函数式接口。
定义FunctionalInterface 接口
/**
* 使用@FunctionalInterface检查函数式接口格式问题
* 要求当前接口中有且只有一个缺省属性为public abstract的方法
*
* @author Anonymous 2020/3/11 9:55
*/
@FunctionalInterface
public interface FunctionalType {
void test();
}
自定义Demo1类
/**
* 自定义函数式接口作为方法的参数演示
*
* @author Anonymous 2020/3/11 9:55
*/
public class Demo1 {
public static void main(String[] args) {
/*
使用匿名内部类来完成函数式接口的使用,但是这种方式有悖于函数式接口的目的
Low
useFunctionalInterface(new FunctionalType() {
@Override
public void test() {
System.out.println("匿名内部类的匿名对象直接作为方法的参数。");
}
});
int(*) (char **, int *)
C语言中的函数指针
如果是C语言中,这需要的参数是方法名
*/
useFunctionalInterface(() -> System.out.println("函数式接口 lambda表达式实现完成方法,实现目的"));
}
/**
* 使用一个函数式接口作为方法的参数
*
* @param ft 函数式接口的实现类对象,或者说直接操作本质,直接传入Lambda表达式
*/
public static void useFunctionalInterface(FunctionalType ft) {
ft.test();
}
}
Supplier<T> 生产者, 返回一个指定类型的数据
Consumer<T> 消费者, 消耗一个指定类型的数据
Predicate<T> 判断调节,过滤使用
Function<T,R> 类型转换,根据你指定的类型T, 转换成对应类型R
有且只有一个方法 T get(); 不需要参数,返回指定T类型数据
/**
* Supplier函数式接口演示
*
* @author Anonymous 2020/3/11 14:44
*/
public class Demo1 {
public static void main(String[] args) {
String msg1 = "异常位置XXX,";
String msg2 = "异常问题XXX,";
String msg3 = "异常时间XXX";
/*
这里需要的是一个函数式接口,直接传入一个lambda表达式
*/
log(Level.HIGH, () -> {
System.out.println("Lambda表达式执行!!!");
return msg1 + msg2 + msg3;
});
/*
Lambda表达式优化
*/
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) {
/*
Supplier函数式接口利用get方法,提供对应的返回指定String类型数据的操作
*/
if (Level.HIGH == level) {
// 通过函数式接口获取调用对应的returnLogMessage()方法
System.err.println(supplier.get());
}
}
}
操作使用的方式是 void accept(T t); 根据接口指定的数据类型接收对应数据,进行处理和消费,对外没有任何的返回
/**
* 使用Consumer处理数据
*
* @author Anonymous 2020/3/11 15:24
*/
public class Demo1 {
public static void main(String[] args) {
// 该方法需要的参数是一个String类型,同时使用Consumer接口处理数据
// 因为Consumer接口是一个函数式接口,可以使用Lambda表达式
testConsumer("宫保鸡丁,番茄牛腩,酱牛肉,黄焖鸡米饭", (str) -> {
String[] split = str.split(",");
for (String s : split) {
System.out.println(s);
}
});
}
/**
* 给予当前方法一个String类型,通过Consumer函数式接口中的accept方法完成对应
* 字符串处理
*
* @param str String类型字符串
* @param consumer Consumer处理数据的函数式接口
*/
public static void testConsumer(String str, Consumer<String> consumer) {
consumer.accept(str);
}
}
Predicate一般用于调节判断,过滤数据的方法 函数式接口中指定的方法 boolean test(T t); 处理T类型数据,返回boolean true / false
①基本使用
/**
* 演示Predicate<T>基本使用
* boolean test(T t)
*
* @author Anonymous 2020/3/11 16:11
*/
public class Demo1 {
public static void main(String[] args) {
// Predicate函数式接口,使用Lambda表达式作为方法的参数
boolean b = testPredicate("郑州奥力给!!!中国奥力给!!!",
(str) -> {
return str.contains("加油");
});
System.out.println("ret : " + b);
System.out.println("---------------------------");
/*
优化Lambda表达式,
因为是一个参数,小括号可以省略
就一行代码,大括号可以省略
return也可以省略
*/
testPredicate("郑州奥力给!!!中国奥力给!!!", str -> str.contains("加油"));
}
/**
* 使用Predicate函数式接口利用boolean test(T t)对于当前数据进行判断操作,
* 返回boolean类型数据
*
* @param str 需要进行判断数据的String类型字符串
* @param pre 处理使用Predicate函数式接口
* @return 判断接口是否满足要求,满足返回true,不满足返回false
*/
public static boolean testPredicate(String str, Predicate<String> pre) {
return pre.test(str);
}
}
②与 :and
/**
* Predicate and使用
* default修饰方法add(Predicate<T> pre)
* and就是逻辑运算符里面的 &&
* 同真为真,有假【即】假
* 需要对两个Predicate进行判断处理
*
* 例如:
* pre1.test(str) && pre2.test(srt);
* ==> pre1.and(pre2).test(str);
*
* @author Anonymous 2020/3/11 16:19
*/
public class Demo2 {
public static void main(String[] args) {
/*
这里需要量Predicate接口,使用Lambda
*/
boolean ret = testAnd("赶紧复工吧,不要搞事情了!!!",
str -> str.length() > 5,
str -> str.startsWith("赶紧"));
System.out.println(ret);
}
/**
* 组合判断
*
* @param str 需要判断的字符串
* @param pre1 判断方式1
* @param pre2 判断方式2
* @return 处理结果 true, false
*/
public static boolean testAnd(String str, Predicate<String> pre1, Predicate<String> pre2) {
// return pre1.test(str) && pre2.test(str)
return pre1.and(pre2).test(str);
}
}
③或 : or
/**
* Predicate or演示
*
* @author Anonymous 2020/3/11 16:32
*/
public class Demo3 {
public static void main(String[] args) {
boolean ret = testOr("国家之强大,国外人羡慕不得~~",
str -> str.length() < 10,
str -> str.contains("国家"));
System.out.println(ret);
}
/**
* or 组合判断
*
* @param str 需要判断的字符串
* @param pre1 判断方式1
* @param pre2 判断方式2
* @return 处理结果 true, false
*/
public static boolean testOr(String str, Predicate<String> pre1, Predicate<String> pre2) {
// return pre1.test(str) || pre2.test(str);
return pre1.or(pre2).test(str);
}
}
④非 :negate
/**
* Predicate negate()操作
*
* @author Anonymous 2020/3/11 16:36
*/
public class Demo4 {
public static void main(String[] args) {
boolean ret = testNegate("疫情总会过去的!!!",
str -> str.length() < 5);
System.out.println(ret);
}
/**
* negate操作
*
* @param str 字符串
* @param pre Predicate函数式接口
* @return 处理结果
*/
public static boolean testNegate(String str, Predicate<String> pre) {
// return !pre.test(str);
return pre.negate().test(str);
}
}
使用R apply(T t) 转换指定类型T到R
/**
* Function<T, R>
* default修饰andThen方法使用
*
* @author Anonymous 2020/3/11 17:01
*/
public class Demo2 {
public static void main(String[] args) {
String s = testAndThen(10,
i -> i + "",
i -> i + "测试");
System.out.println(s);
}
/**
* 两次转换过程
*
* @param i 需要处理的类型
* @param fun1 Function函数接口
* @param fun2 Function函数接口
* @return String类型
*/
public static String testAndThen(int i, Function<Integer, String> fun1, Function<String, String> fun2) {
// andThen使用,最后apply方法参数类型是fun1要求的转换参数类型
return fun1.andThen(fun2).apply(i);
}
}