黑马程序员技术交流社区

标题: [ Java ] 【成都校区】@FunctionInterface [打印本页]

作者: 汪洪吉    时间: 2019-4-25 08:45
标题: [ Java ] 【成都校区】@FunctionInterface
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
函数式接口可以被隐式转换为lambda表达式。
函数式接口可以现有的函数友好地支持 lambda。

介绍

函数式接口其实就是一个抽象接口类,在Java 8之前已有的函数式接口有以下。

?
1
2
3
java.lang.Runnable
java.util.concurrent.Callable
java.util.Comparator
等等...

使用方法

其实上述所说的接口类只需要使用FunctionalInterface注解修饰,就成为了Java中的函数式接口。比如JDK中Callable接口定义

?
1
2
3
4
@FunctionalInterface
public interface Callable<V> {
  V call() throws Exception;
}
就这么简单。

现在来讲讲Java 8新增Function接口。下面是其定义

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// T 是传入参数
// R 是返回参数
@FunctionalInterface
public interface Function<T, R> {
  R apply(T t);
  default <V> Function<V, R> compose(Function<? super V, ? extends T> before {
    Objects.requireNonNull(before);
    return (V v) -> apply(before.apply(v));
  }

  default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
    Objects.requireNonNull(after);
    return (T t) -> after.apply(apply(t));
  }
  static <T> Function<T, T> identity() {
    return t -> t;
  }
}
他可以理解为C语言中的函数指针(个人看法)。

在实际使用中,apply方法使用比较广泛。compose/andThen多用于两个以上函数接口并且执行上有先后顺序的场景下。

在具体业务代码中,我一般结合BiFuncton/Supplier一起使用。BiFunction支持2个参数的,Function只支持一个参数。Supplier可以用来存储具体需要的值,通过get来获取。

例子

引用平时工作的代码。该例子主要规避了多个判断条件if/else造成代码臃肿的,同时也可以把相同的业务逻辑抽象出函数接口,从而可以在多处代码重用。具体代码如下。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Function<Object, Integer> actionTest1 = (object) -> {
  // logic
  return 0;
};
Function<Object, Integer> actionTest2 = (object) -> {
  // logic
  return 0;
};
public Supplier<Map<Integer, Function<Object, Integer>>> actionSupplier = () -> {
    Map<Integer, Function<Object, Integer>> maps = new HashMap<>();
    maps.put(1, actionTest1);
    maps.put(2, actionTest2);
    return maps;
};
// 具体使用
public void test(int type, Object object) {
  Optional.ofNullable(actionSupplier.get().get(type)).ifPresent(x -> x.apply(v, object));
  // if/else 逻辑
  if (type == 1) {
    // test1 logic
  } else if (type == 2) {
    // test2 logic
  }
}
总结

个人认为,在业务逻辑分支判断较多的场景,是比较适合使用Function的,而且还有以下几点好处

代码看上去比较简洁
相同逻辑可以重用(当然封装成函数也是可以的~)
代码后期比较好维护点。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2