利用Java8 函数式接口优化代码

314 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

  • 个人简介:微信公众号关注:SteveCode。为您分享更多的知识学术。生于忧患死于安乐
  • 专注Java技术干货分享,Java基础技术、数据结构、相关工具、Spring全家桶、intellij idea...... 源码地址master

首先看一段代码

public class Test {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("老写法");
            }
        });
    
        new Thread(() -> {
            System.out.println("函数式接口新写法");
        });
    }
}

为什么可以这么写?

public class Test {
    public static void main(String[] args) {

    new Thread(()->{
        System.out.println("songxianyang");
    });
    }
}

答: 函数式接口

先说一个注解

@FunctionalInterface

  • 用的信息注释类型,以指示在接口类型声明旨在是一个功能接口由Java语言规范所定义的。 在概念上,功能界面只有一个抽象方法。如果接口声明了一个抽象方法覆盖的公共方法之一java.lang.Object ,也不会向接口的抽象方法计数统计以来的接口的任何实施都会有一个实现从java.lang.Object或其他地方。

    请注意,可以使用lambda表达式,方法引用或构造函数引用创建函数接口的实例。

    如果使用此注释类型注释类型,则编译器需要生成错误消息,除非:

    • 类型是接口类型,而不是注释类型,枚举或类。
    • 注释类型满足功能界面的要求。

有哪些函数式接口

new Runnable();无参无返回型函数,没有参数也没有返回值
new Function();  供给型函数,有参有返回型函数。
new Consumer(); 消费型函数,一个参数,没有返回值
new Supplier(); 供给型函数,有参有返回型函数。

底层源码

Runnable

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

Function

@FunctionalInterface
public interface Function<T, R> {

    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);

    /**
     * Returns a composed function that first applies the {@code before}
     * function to its input, and then applies this function to the result.
     * If evaluation of either function throws an exception, it is relayed to
     * the caller of the composed function.
     *
     * @param <V> the type of input to the {@code before} function, and to the
     *           composed function
     * @param before the function to apply before this function is applied
     * @return a composed function that first applies the {@code before}
     * function and then applies this function
     * @throws NullPointerException if before is null
     *
     * @see #andThen(Function)
     */
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    /**
     * Returns a composed function that first applies this function to
     * its input, and then applies the {@code after} function to the result.
     * If evaluation of either function throws an exception, it is relayed to
     * the caller of the composed function.
     *
     * @param <V> the type of output of the {@code after} function, and of the
     *           composed function
     * @param after the function to apply after this function is applied
     * @return a composed function that first applies this function and then
     * applies the {@code after} function
     * @throws NullPointerException if after is null
     *
     * @see #compose(Function)
     */
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    /**
     * Returns a function that always returns its input argument.
     *
     * @param <T> the type of the input and output objects to the function
     * @return a function that always returns its input argument
     */
    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

Consumer

@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

    /**
     * Returns a composed {@code Consumer} that performs, in sequence, this
     * operation followed by the {@code after} operation. If performing either
     * operation throws an exception, it is relayed to the caller of the
     * composed operation.  If performing this operation throws an exception,
     * the {@code after} operation will not be performed.
     *
     * @param after the operation to perform after this operation
     * @return a composed {@code Consumer} that performs in sequence this
     * operation followed by the {@code after} operation
     * @throws NullPointerException if {@code after} is null
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

Supplier

@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

代码实现

  • 需求:简化if...else{} 可以采用

代码结构

image.png

MyUtils

package com.example.demo.myfunction.impl;

import com.example.demo.myfunction.ExceptionFunction;
import com.example.demo.myfunction.FunctionIfEOrElse;

/**
 * 功能描述:
 *
 * @author Songxianyang
 * @date 2022-04-27 18:10
 */
public final class MyUtils {
    /**
     * if else 加工
     * @param b
     * @return
     */
    public static FunctionIfEOrElse isTrue(Boolean b) {
        return (runnableTrue, runnableFalse) -> {
            if (b) {
                runnableTrue.run();
            } else {
                runnableFalse.run();
            }
        };
    }
    
    /**
     * 打印消息 测试
     * @return
     */
    public static ExceptionFunction isMsg() {
        return msg1 -> {
            System.out.println(msg1);
        };
        
    }
}

ExceptionFunction

/**
 * 功能描述:异常信息输出
 *
 * @author Songxianyang
 * @date 2022-04-27 18:26
 */
@FunctionalInterface
public interface ExceptionFunction {
    /**
     * 异常信息输出
     * @param msg
     */
    void throwOut(String msg);
    
}

FunctionIfEOrElse

/**
 * 功能描述:执行对应的分支
 *
 * @author Songxianyang
 * @date 2022-04-27 17:42
 */
@FunctionalInterface
public interface FunctionIfEOrElse {
    /**
     * 执行对应的分支
     * @param runnableTrue
     * @param runnableFalse
     */
    void print(Runnable runnableTrue,Runnable runnableFalse);
}

测试类


/**
 * 功能描述:
 *
 * @author Songxianyang
 * @date 2022-04-27 18:10
 */
public class PrintTest {
    public static void main(String[] args) {
        MyUtils.isTrue(true).print(() -> {
            System.out.println("执行true业务代码");
        }, () -> {
            System.out.println("执行FALSE业务代码");
        });
        RuntimeException exception = new RuntimeException("我报错了 请指示");
        MyUtils.isMsg().throwOut(exception.getMessage());
    }

image.png

总结

  • Function函数可以大大的简化代码。看着就是优雅好懂

新特性文章可以

Java8新特性之lambda与stream-骚操作