package cn.t02;
/**
* 函数式接口:
* 函数式接口即适用于函数式编程场景的接口,在Java中函数式编程的体现是Lambda.
* 因此函数式接口可以适用于Lambda使用的接口.
* 只有在确保接口中有且只有一个抽象方法时,Java中的Lambda才能顺利的推导!
*
* 语法糖:语法糖是指使用更加方便,但是原理不变的代码语法.
* 例如:集合遍历使用的for-Each语法,其底层实现原理是迭代器.
* 那for-Each对于迭代循环代码来说就是他的语法糖!
*
* 而Lambda在应用层面来看,可以把其当作匿名内部类的语法糖.(二者原理上不一样)
*
* @FunctionalInterface:
* 为了保证接口中有且只有一个抽象方法,Java中提供了一个用来验证的注解;
* 一旦在接口上标注了@FunctionalInterface,编译器就会强制检查接口是否有且只有一个
* 抽象方法,否则就会报错.
*
* 需要注意:即使不使用@FunctionalInterface注解,只要满足函数式接口的定义,就仍然是
* 一个函数式接口,使用起来效果是一样的!
*
* 好,接下来就Lambda函数式接口来进行Demo演示!
*
*/
/**
* 无参无返回函数式接口
*
* 首先,明确一下接下来的Demo架构;
*
* 第一步Demo会演示: 无参无返回函数式接口;
* 第二步Demo会演示: 有参有返回函数式接口;
* 第三步Demo会演示: Lambda的延迟加载机制;
* 第四步Demo会演示: 将Lambda表达式作为参数和返回值使用;
*
*
* 好,接下来开始第一步的Demo演示:
*
* 1. 无参无返回函数式接口;
*
*/
@FunctionalInterface
public interface FunctionGo {
/**
* 接口中抽象方法的public abstract可以省略!
*/
void gooing();
}
/**
* 外部类:
* 用来临时测试!
*/
class Test {
/**
* 调用自定义函数式接口:
* 最典型的方法就是将其作为方法参数;
*
* 使用自定义的函数式接口作为方法参数!
* @param fg
*/
private static void goining(FunctionGo fg) {
// 调用自定义函数式接口的方法!
fg.gooing();
}
/**
* Java主函数|入口!
* @param args
*/
public static void main(String[] args) {
/**
* 调用使用函数式接口的方法;
*/
goining(() -> {
System.out.println("123");
System.out.println(888);
});
}
}
package cn.first;
import java.sql.SQLOutput;
/**
* 2. 有参有返回函数式接口
*
* ok,上面定义的函数式接口为无参无返回函数式接口;
* 下面开始第二步Demo演示:
* 有参有返回函数式接口;
*/
@FunctionalInterface
public interface FunIter {
/**
* 抽象方法;
* @return String;
*/
String gooing();
}
// 内部类;
class FunClass {
// Lambda典型封装结构;
private static void goining(int level, FunIter funIter) {
// 内部实现;
if(level/7 == 0) {
// while循环;
while (level > 0) {
// 递减运算符;
level--;
// 控制台打印;
System.out.print(funIter.gooing());
}
/**
* 空打印(控制台打印);
* 目的: 当余数整除打印完一轮长度的字符后,进行换行;
*/
System.out.println();
}
}
/**
* Java主函数|入口;
* @param args
*/
public static void main(String[] args) {
// 循环遍历<=100的整数集;
for (int i=0; i<=100; i++) {
// 调用封装函数;
goining(i, () -> "*");
}
}
}
package cn.fouth;
/**
* 3. Lambda的延迟加载机制
*/
public class LazyLambda {
/**
* 下面是普通的日志加载;
* @param level
* @param msg
*/
private static void log(int status, String msg) {
// 参数状态判断;
if (status == 1) {
// 控制台输出打印;
System.out.println(msg);
}
}
/**
* 下面是Lambda形式封装的函数;
* @param status
* @param messageInter
*/
private static void toLog(int status, MessageInter messageInter) {
// 参数状态判断;
if (status == 1) {
/**
* 控制台输出打印;
* messageInter.msg():函数调用;
*/
System.out.println(messageInter.msg());
}
}
public static void main(String[] args) {
// 参数初始化;
String a = "Hello";
String b = "World!";
/**
* 调用普通函数;
* 一般这类的函数调用过程中:
* 不管参数条件是否满足,都会进行运算;
*/
// log(2, a+b);
/**
* 调用Lambda接口的函数:
* 可以做到load Lazy;
*/
toLog(1, () -> a+b);
}
}
/**
* 函数式接口定义;
*/
@FunctionalInterface
interface MessageInter {
// 抽象函数;
String msg();
}
package cn.xxx;
import java.util.Arrays;
import java.util.Comparator;
/**
* 4. 将Lambda表达式作为参数和返回值使用;
*/
public class FunInter {
/**
* 1. Lambda表达式作为参数使用;
*
* Lambda函数封装;
* 将Lambda表达式作为参数使用;
* @param runnable
*/
private static void startThread(Runnable runnable) {
// 线程启动;
new Thread(runnable).start();
}
/**
* 2. Lambda表达式作为返回值;
*
* 排序:
* 数组自定义排序;
* @return
*/
private static Comparator<String> GetIndex() {
return (a,b) -> b.length()-a.length();
}
/**
* Java主函数|入口;
* @param args
*/
public static void main(String [] args) {
/**
* 1. 调用以Lambda表达式为参数的函数;
*/
startThread(() -> System.out.println("线程任务执行!"));
// 实例化一个字符串类型的数组;
String [] arr = {"a","bbb","ccccd"};
// 初次打印数组内容;
System.out.println(Arrays.toString(arr));
/**
* 2. 调用将Lambda表达式作为返回值的函数;
*
* 数组排序:
* 调用自定义排序函数进行排序;
*/
Arrays.sort(arr,GetIndex());
// 二次打印数组内容;
System.out.println(Arrays.toString(arr));
}
}