函数式接口

函数式接口

1. 函数式接口
1.1 概述
	如果说一个接口内有且只有一个方法,而且该方法是一个缺省属性为public abstract方法,该接口可以称之为是一个函数式接口。
	自定义函数式接口,还有系统中提供的函数式接口
	Comparator<T> Runnable
	
	可以直接理解JDK1.8的新特征,Lambda表达式来使用。
	
	Lambda表达式对比匿名内部类使用
		1. 简化了代码结构
		2. 节约了内存资源
		3. 让程序员更加关注,我要做什么,而不是为了做什么需要完成什么
1.2 @FunctionalInterface 使用
类似于
	@Override
	开启代码重写格式严格检查
/**
 * 使用@FunctionalInterface检查函数式接口格式问题
 * 要求当前接口中有且只有一个缺省属性为public abstract的方法
 *
 * @author Anonymous 2020/3/11 9:55
 */
@FunctionalInterface
public interface FunctionalType {
    void test();
}
代码中使用函数式接口
	1. 让程序的目的性更强
	2. 提供复用,普适性的价值
	3. 节约资源
2. 函数式编程思想
2.1 Lambda延迟执行
2.1.1 日志记录
日志是否保存会存在等级限制
	演示一个根据不同的等级来记录log日志
要求:	
	等级 == 1 记录log日志,其他情况不记录
package com.qfedu.b_lambda;

enum Level {
    /**
     * 枚举测试
     */
    HIGH, MIDDLE, LOWER
}

/**
 * 日志等级记录操作
 *
 * @author Anonymous 2020/3/11 10:17
 */
public class Demo1 {
    public static void main(String[] args) {
        /*
        这里存问题:
            "异常位置XXX," + "异常问题XXX," + "异常时间XXX" 字符叠加过程,会产生
            5个字符串
            这5个字符串如果Level.HIGH等级是有用的,但是除此之外是没有任何作用的。
            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);
        }
    }
}
2.1.2 使用函数式接口提供日志信息功能
这里需要一个函数式接口,返回值类型是String类型,其他的无所谓。
package com.qfedu.b_lambda;

/**
 * 提供返回值为String类型方法的函数式接口
 *
 * @author Anonymous 2020/3/11 10:52
 */
@FunctionalInterface
public interface LogMessage {
    /**
     * 函数式接口中方法内容,该方法的返回值是String类型
     *
     * @return String类型返回值
     */
    String returnLogMessage();
}
package com.qfedu.b_lambda;

/**
 * 使用函数式接口完成Log日志记录问题
 *
 * @author Anonymous 2020/3/11 10:53
 */
public class Demo2 {
    public static void main(String[] args) {
        String msg1 = "异常位置XXX,";
        String msg2 = "异常问题XXX,";
        String msg3 = "异常时间XXX";

        log(Level.LOWER, () -> {
            System.out.println("Lambda表达式执行!!!");
            return msg1 + msg2 + msg3;
        });
    }

    /**
     * 根据日志等级Level来确定是否需要记录日志
     *
     * @param level Level枚举类型,有三个数据 HIGH MIDDLE LOWER
     * @param lm LogMessage函数式接口做方法的参数
     */
    public static void log(Level level, LogMessage lm) {
        /*
        发现当Level等级为HIGH,执行对应的lm.returnLogMessage();
        Level等级不是HIGH不执行对应的方法。

        Lambda执行延迟问题不是Lambda效率执行慢,而是在执行之前多了一个判断
        是在判断之后才可以执行对应的代码。
            不执行代码字符串不会产生拼接导致的资源浪费问题,从而提高效率。
         */
        if (Level.HIGH == level) {
            // 通过函数式接口获取调用对应的returnLogMessage()方法
            System.err.println(lm.returnLogMessage());
        }
    }

    public static void testEnum(int level) {
        if (Level.HIGH.getStatus() == level) {

        }
    }
}
2.2 Lambda作为方法参数和返回值
package com.qfedu.b_lambda;

/**
 * Runnable接口函数式接口使用,作为方法的参数
 *
 * @author Anonymous 2020/3/11 11:18
 */
public class Demo3 {
    public static void main(String[] args) {
        // 匿名内部类来完成对应当前Runnable接口实现类对象使用,作为Thread构造方法参数
        // low
        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<T>
	利用一些返回值作为方法中操作的调节
	
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 11:25
 */
public class Demo4 {
    public static void main(String[] args) {
        /*
        字符串排序默认是一个字典顺序
         */
        String[] arr = {"eeeeeeee", "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());

        Arrays.sort(arr, Comparator.comparingInt(String::length));
        /*
        Comparator.comparingInt(String::length)

        Comparator:接口
        comparingInt:按照Int类型方式比较判断
        String:表示比较的类型是String,比较什么类型用什么类型
        length:按照String类型的哪一种方式比较
        */
        System.out.println(Arrays.toString(arr));


    }

    /**
     * 按照字符串长度排序,返回值类型是一个Comparator<String>接口
     * 这里需要完成Comparator接口中的compare方法
     *
     * @return 已经完成方法体的Comparator接口,并且数据类型是String类型
     */
    public static Comparator<String> stringComparator() {
        /*
        public interface Comparator<T> {
            int compare(T o1, T o2);
        }
         */
        return (a, b) -> b.length() - a.length();
    }
}

3. Java中提供的常用函数式接口
3.1 JDK常用函数式接口概述
java.util.function包名 。提供了很多函数式接口
	规范了一些操作,提升了开发效率,更加专注于目的性!!!
	
	Supplier<T> 生产者, 返回一个指定类型的数据
	Consumer<T> 消费者, 消耗一个指定类型的数据
	Predicate<T> 判断调节,过滤使用
	Function<T,R> 类型转换,根据你指定的类型T, 转换成对应类型R
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值