1、理解函数式接口

JDK 1.8 API包含了很多内建的函数式接口,在老Java中常用到的比如Comparator、Runnable、Callable接口,都增加了@FunctionalInterface注解,以便能用在lambda上。

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

这个注解,是一个信息型注解。
1、只能用在接口上
2、使用此注解的接口,有且仅有一个抽象方法。
3、使用此注解的接口,可以有静态方法和默认方法。
4、使用此注解的接口,可以重写Object中方法,比如equals,toString。
5、该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查,如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。

2、使用样例

定义接口1:
@FunctionalInterface
public interface BranchFunction {
    void trueOrFalse(Runnable trueRunnable, Runnable falseRunnable);
}
定义接口2:
@FunctionalInterface
public interface BranchTrueFunction {
    void trueThen(Runnable trueRunnable);
}
定义个工具类:
public class ConditionUtil {

    /***
     * @Description: 解决if () {} else {} 问题,判断真和假
     * @Author 王结胜 wangjiehseng
     * @Date 2022/9/3 23:50
     */
    public static BranchFunction isTrueOrFalse(boolean b) {
        return (t, f) -> {
            if (b) {
                t.run();
            } else {
                f.run();
            }
        };
    }

    /***
     * @Description: 解决if () {}
     * @Author 王结胜 wangjiehseng
     * @Date 2022/9/3 23:50
     */
    public static BranchTrueFunction isTrueOr(boolean b) {
        return (t) -> {
            if (b) {
                t.run();
            }
        };
    }

}

单元测试:

    @Test
    public void isTrueOrFalseTest () {
        String name = "wang";
        boolean flag = StrUtil.equals("wang", name);
        ConditionUtil.isTrueOrFalse(flag).trueOrFalse(() -> System.out.printf("真"),
                () -> System.out.printf("假"));
        //输出:真
    }

    @Test
    public void isTrueOrTest () {
        boolean flag = true;
        ConditionUtil.isTrueOr(flag).trueThen(() -> System.out.printf("真"));
        //输出:真
    }

3、java.util.function

nametypedescriptionmethod
ConsumerConsumer接收T对象,不返回值void accept(T t)
PredicatePredicate接收T对象并返回booleanboolean test(T t)
FunctionFunction<T,R>接收T对象,返回R对象R apply(T t)
SupplierSupplier提供T对象(例如工厂),不接收值T get()

Consumer
消费某个对象。常用Iterable接口的forEach方法需要传入Consumer,大部分集合类都实现了该接口,用于返回Iterator对象进行迭代。

Predicate
判断对象是否符合某个条件。比如ArrayList的removeIf(Predicate),可以自定义条件,删除相应的元素。

Function
实现一个"一元函数",即传入一个值经过函数的计算返回另一个值。比如 HashMap.computeIfAbsent方法,如果指定的Key未与值关联,使用函数返回值替换。

Supplier
创建一个对象(工厂类)比如Optional.orElseGet(Supplier<? extends T>):当this对象为null,就通过传入supplier创建一个T返回。