java中functional interface的分类和使用

简介

java 8引入了lambda表达式,lambda表达式实际上表示的就是一个匿名的function。java

在java 8以前,若是须要使用到匿名function须要new一个类的实现,可是有了lambda表达式以后,一切都变的很是简介。git

咱们看一个以前讲线程池的时候的一个例子:github

//ExecutorService using class
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(new Runnable() {
            @Override
            public void run() {
            log.info("new runnable");
            }
        });
复制代码

executorService.submit须要接收一个Runnable类,上面的例子中咱们new了一个Runnable类,并实现了它的run()方法。app

上面的例子若是用lambda表达式来重写,则以下所示:ide

//ExecutorService using lambda
        executorService.submit(()->log.info("new runnable"));
复制代码

看起是否是很简单,使用lambda表达式就能够省略匿名类的构造,而且可读性更强。this

那么是否是全部的匿名类均可以用lambda表达式来重构呢?也不是。lua

咱们看下Runnable类有什么特色:spa

@FunctionalInterface
public interface Runnable 复制代码

Runnable类上面有一个@FunctionalInterface注解。这个注解就是咱们今天要讲到的Functional Interface。线程

Functional Interface

Functional Interface是指带有 @FunctionalInterface 注解的interface。它的特色是其中只有一个子类必需要实现的abstract方法。若是abstract方法前面带有default关键字,则不作计算。code

其实这个也很好理解,由于Functional Interface改写成为lambda表达式以后,并无指定实现的哪一个方法,若是有多个方法须要实现的话,就会有问题。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}
复制代码

Functional Interface通常都在java.util.function包中。

根据要实现的方法参数和返回值的不一样,Functional Interface能够分为不少种,下面咱们分别来介绍。

Function:一个参数一个返回值

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)复制代码

通常咱们在对集合类进行处理的时候,会用到Function。

Map<String, Integer> nameMap = new HashMap<>();
        Integer value = nameMap.computeIfAbsent("name", s -> s.length());
复制代码

上面的例子中咱们调用了map的computeIfAbsent方法,传入一个Function。

上面的例子还能够改写成更短的:

Integer value1 = nameMap.computeIfAbsent("name", String::length);
复制代码

Function没有指明参数和返回值的类型,若是须要传入特定的参数,则可使用IntFunction, LongFunction, DoubleFunction:

@FunctionalInterface
public interface IntFunction<R> {

    /** * Applies this function to the given argument. * * @param value the function argument * @return the function result */
    R apply(int value);
}
复制代码

若是须要返回特定的参数,则可使用ToIntFunction, ToLongFunction, ToDoubleFunction:

@FunctionalInterface
public interface ToDoubleFunction<T> {

    /** * Applies this function to the given argument. * * @param value the function argument * @return the function result */
    double applyAsDouble(T value);
}
复制代码

若是要同时指定参数和返回值,则可使用DoubleToIntFunction, DoubleToLongFunction, IntToDoubleFunction, IntToLongFunction, LongToIntFunction, LongToDoubleFunction:

@FunctionalInterface
public interface LongToIntFunction {

    /** * Applies this function to the given argument. * * @param value the function argument * @return the function result */
    int applyAsInt(long value);
}
复制代码

BiFunction:接收两个参数,一个返回值

若是须要接受两个参数,一个返回值的话,可使用BiFunction:BiFunction, ToDoubleBiFunction, ToIntBiFunction, ToLongBiFunction等。

@FunctionalInterface
public interface BiFunction<T, U, R> {

    /** * Applies this function to the given arguments. * * @param t the first function argument * @param u the second function argument * @return the function result */
    R apply(T t, U u);
复制代码

咱们看一个BiFunction的例子:

//BiFunction
        Map<String, Integer> salaries = new HashMap<>();
        salaries.put("alice", 100);
        salaries.put("jack", 200);
        salaries.put("mark", 300);

        salaries.replaceAll((name, oldValue) ->
                name.equals("alice") ? oldValue : oldValue + 200);
复制代码

Supplier:无参的Function

若是什么参数都不须要,则可使用Supplier:

@FunctionalInterface
public interface Supplier<T> {

    /** * Gets a result. * * @return a result */
    T get();
}
复制代码

Consumer:接收一个参数,不返回值

Consumer接收一个参数,可是不返回任何值,咱们看下Consumer的定义:

@FunctionalInterface
public interface Consumer<T> {

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

看一个Consumer的具体应用:

//Consumer
        nameMap.forEach((name, age) -> System.out.println(name + " is " + age + " years old"));
复制代码

Predicate:接收一个参数,返回boolean

Predicate接收一个参数,返回boolean值:

@FunctionalInterface
public interface Predicate<T> {

    /** * Evaluates this predicate on the given argument. * * @param t the input argument * @return {@code true} if the input argument matches the predicate, * otherwise {@code false} */
    boolean test(T t);
复制代码

若是用在集合类的过滤上面那是极好的:

//Predicate
        List<String> names = Arrays.asList("A", "B", "C", "D", "E");
        List<String> namesWithA = names.stream()
                .filter(name -> name.startsWith("A"))
                .collect(Collectors.toList());
复制代码

Operator:接收和返回一样的类型

Operator接收和返回一样的类型,有不少种Operator:UnaryOperator BinaryOperator ,DoubleUnaryOperator, IntUnaryOperator, LongUnaryOperator, DoubleBinaryOperator, IntBinaryOperator, LongBinaryOperator等。

@FunctionalInterface
public interface IntUnaryOperator {

    /** * Applies this operator to the given operand. * * @param operand the operand * @return the operator result */
    int applyAsInt(int operand);
复制代码

咱们看一个BinaryOperator的例子:

//Operator
        List<Integer> values = Arrays.asList(1, 2, 3, 4, 5);
        int sum = values.stream()
                .reduce(0, (i1, i2) -> i1 + i2);
复制代码

总结

Functional Interface是一个很是有用的新特性,但愿你们可以掌握。

本文的例子:github.com/ddean2009/l…

更多内容请访问 www.flydean.com

相关文章
相关标签/搜索