Java中的小知识 ------- 函数式接口

概念

如果说一个接口内有且只有一个方法,而且该方法是一个缺省属性为public abstract方法,那么该接口可以称之为函数式接口
有自定义函数式接口,还有系统中提供的函数式接口,例如:Comparator<T> 、 Runnable
可以直接利用JDK1.8的新特征,Lambda来使用。
Lambda表达式对比匿名内部类使用:
    1.简化了代码接口
    2.节约了内存资源
    3.让程序员更加关注“我要做什么”,而不是“为了做什么而完成什么”

@FunctionalInterface使用

类似于 @Override,开启代码重写格式严格检查

格式:

/**
 * 使用FunctionalInterface检查函数式接口格式问题
 * 要求当前接口中有且只有一个缺省属性为public abstract的方法
 * @Author kk
 * @Date 2020/3/11 9:56
 */
@FunctionalInterface
public interface FunctionalType {
    void test();
}

代码中使用函数式接口

1.让程序的目的性更强

2.提供复用,普适性的价值

3.节约资源

函数式编程思想

Lambda延迟执行

日志记录

日志是否保存会存在等级限制;演示一个根据不同等级来记录log日志

要求:

等级==1 记录log日志,其他情况不记录

使用函数式接口提供日志信息功能

这里需要一个函数式接口,返回值类型是String类型,其他的无所谓

Lambda作为方法参数和返回值

参数演示:

Runnbale接口
 

package com.wcc.b_Lambda;

/**
 * Runnable接口函数式接口使用,作为方法的参数
 * @Author kk
 * @Date 2020/3/11 11:18
 */
public class Demo3 {
    public static void main(String[] args) {
        //匿名内部类,完成对应当前Runnable接口实现类对象使用,作为Thread构造方法参数
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("现成代码");
            }
        }).start();
        
        //Lambda直接作为方法的参数
        Thread thread = new Thread(() -> System.out.println("线程执行"), "线程");
        thread.start();
    }

}

 

Java中提供过的比较接口Comparator<T>,利用一些返回值作为方法中操作的调节

public interface Comparator<T>{

    int compare<T o1, T o2>
}

 

package com.wcc.b_Lambda;

import java.util.Arrays;
import java.util.Comparator;

/**
 * Lambda完成函数式接口,利用返回值作为其他操作返回的数据
 * @Author kk
 * @Date 2020/3/11 11:25
 */
public class Demo4 {
    public static void main(String[] args) {
        /*
            字符串排序,默认是一个字典顺序
         */
        String[] arr = {"a", "cccccccccccccccc", "bb", "dddd"};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));

        //利用一个函数式接口完成的方法,利用方法的返回值作为当前sort方法运行
        //所需参数,该参数用于比较规则约束
        Arrays.sort(arr,stringComparator());
        System.out.println(Arrays.toString(arr));

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

    }

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

Java中提供的常用函数式接口

JDK常用函数式接口概述

java.util.function包名,提供了很多函数式接口;规范了一些操作,提升了开发效率,更加专注于目的性

Supplier<T>生产者,返回一个指定类型的数据
Consumer<T>消费者,小号一个指定类型的数据
Predicate<T>判断条件,过滤使用
Function<T,R>类型转换

Supplier<T>生产者,返回一个指定类型的数据

java.util.function.Supplier<T>
    有且只有一个方法
        T get();
        不需要参数,返回指定T类型数据
package com.wcc.b_Lambda;

import java.util.function.Supplier;

/**
 * Supplier函数式接口演示
 * @Author kk
 * @Date 2020/3/11 10:53
 */
public class Demo2 {
    public static void main(String[] args) {
        String msg1 = "异常位置XXXX";
        String msg2 = "异常问题XXXX";
        String msg3 = "异常时间XXXX";

        //这里需要的是一个函数式接口,直接传入一个lambda表达式
        log(Level.HIGH,() -> {
            System.out.println("Lambda表达式执行!");
            return msg1 + msg2 + msg3;
        });
        /*
            Lambda表达式优化
         */
        log(Level.HIGH,() -> msg1 + msg2 + msg3);
    }

    /**
     * 根据日志等级Level来确定是否需要记录日志
     * @param level Level枚举类型,有三个数据 HIGH,MID,LOW
     * @param supplier Supplier函数式接口,利用T get()完成提供数据操作
     */
    public static void log(Level level, Supplier<String> supplier){
       /*
        Supplier函数式接口利用get方法,提供对应的返回指定String类型数据的操作
        */
        if(Level.HIGH == level){
            //通过函数式接口获取调用对应的returnLogMessage()方法
            System.out.println(supplier.get());
        }
    }
}

Consumer<T>消费者,小号一个指定类型的数据

Consumer<T>
    操作使用的方法式
    void accept(T t);
        根据接口指定的数据类型接收对应数据,进行处理和消费,对外没有任何的返回
        至于处理的过程:展示,处理,计算...跟你没关系
package com.wcc.d_consumer;

import java.util.function.Consumer;

/**
 * 使用Consumer接口处理数据
 * @Author kk
 * @Date 2020/3/11 15:24
 */
public class Demo1 {
    public static void main(String[] args) {
        //该方法需要的参数是一个String类型,同时使用Consumer接口处理数据
        //因为Consumer接口是一个函数式接口,可以使用Lambda表达式
        testConsumer("烧花鸭,烧子鹅,烧雏鸡",(String str) -> {
            String[] split = str.split(",");
            for(String s : split){
                System.out.println(s);
            }
        });

    }

    /**
     * 给予当前方法一个String类型,通过Consumer函数式接口中的accept方法完成
     * 对应字符串处理
     * @param str String类型字符串
     * @param consumer 我们要处理数据的函数式接口
     */
    public static void testConsumer(String str, Consumer<String> consumer){
        consumer.accept(str);

    }
}

Predicate<T>判断条件是否合适,返回true/false,过滤使用

Predicate<T>一般用于调节判断,过滤数据的方法
    函数式接口中指定的方法:
    boolean test(T t);

        处理T类型数据,返回boolean类型
and 与
or 或
negate 非
package com.wcc.e_predicate;

import java.util.function.Predicate;

/**
 * 演示Predicate<T>基本使用
 *      boolean test(T t)
 * @Author kk
 * @Date 2020/3/11 16:12
 */
public class Demo1 {
    public static void main(String[] args) {
        boolean b = testPredicate("奥里给!!!", (str) -> {
            return str.contains("给给!");
        });
        System.out.println("ret:  " + b);
        /*
        优化Lambda表达式
         */
        boolean b1 = testPredicate("给给给!", str -> str.contains("给给给!"));
        System.out.println(b1);
    }

    /**
     * 使用Predicate函数式接口利用boolean test(T t)对于当前数据进行判断操作,
     * 返回boolean类型数据
     *
     * @param str 需要进行判断数据的String类型字符串
     * @param pre 处理使用Predicate函数式接口
     * @return 判断接口是否满足要求
     */
    public static boolean testPredicate(String str, Predicate<String> pre) {
        return pre.test(str);
    }
}

Function<T,R>类型转换

使用R apply(T t)
    转换只当类型T到R
package com.wcc.f_function;

import java.util.function.Function;

/**
 * Function<T R>函数式接口
 *      R apply(T)
 * @Author kk
 * @Date 2020/3/11 16:50
 */
public class Demo1 {
    public static void main(String[] args) {
        String change = change(10, i -> i + "");
        System.out.println(change);

    }

    /**
     * 转换格式的方法,要求数据从Integer类型转换到指定的String类型
     * @param i 需要转换的Integer类型
     * @param fun 转换使用的Function函数式接口
     * @return 返回值是String类型
     */
    public static String change(Integer i, Function<Integer, String> fun){
        return fun.apply(i);
    }
}
发布了21 篇原创文章 · 获赞 32 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42597414/article/details/104790083
今日推荐