java8函数接口

包java.util.function

函数接口为lambda表达式和方法引用提供目标类型,即lambda表达式的类型是函数接口,这看起来似乎有点奇怪,但事实上这是一种确保java语言向后兼容的有效途径。
每个函数接口都只含有一个抽象方法,如:

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("In another thread");
            }
        });
        thread.start(); 
        
        Predict<String> predict = String::isEmpty;

java.util.function中有很多看似名字类似的函数接口,但仔细分析,就会发现他们有以下的命名规则:

  • 1 四个基本的接口 Function
  • 2 与四个基本接口对应的 double, int , long三种泛型参数确定的接口。以及Bi为前缀的抽象方法从一元扩展为二元的函数接
    还有UnaryOperator(扩展Function)和BinaryOperator(扩展BiFunction)。
  • 3 如果接口方法返回的是基本类型,且参数是泛型,则在基本类型前边加To,如ToDoubleBiFunction,ToDoubleFunction,ToIntBiFunction,ToIntFunction,ToLongBiFunction,ToLongFunction.
  • 4 如果泛型参数是基本类型则不加前缀To,如Long/Int/DoubleFunction,Long/Int/DoubleConsumer,Long/Int/DoublePredicate,Long/Int/DoubleSupplier.
  • 5 三个特殊的接收两个参数的Consumer接口函数 ObjDoubleConsumer,ObjIntConsumer,ObjLongConsumer,
  • 6 还有一类特殊的Funtion的接口函数 TypeToTypeFunction,其中Type是Long, Double, Int基本类型。即接收一个基本类型参数,返回另一个基本类型参数
接口函数的三个规则:
  • 1 一个函数接口只能有一个抽象方法。
  • 2 在Object类中属于公共方法的抽象方法不会被视为单一抽象方法。
  • 3 函数接口可以又默认方法和静态方法。

其中满足任何满足单一抽象方法的接口,都会自动视为函数接口。包括Runnable,Callable,Comparator等传统的接口。java8中引入注释 @FunctionalInterface。当违反函数接口的规定时,编译器会报错。需要注意的是,既是注释省略,函数接口的功能也是有效的,注释只是为了编译器强制检查,和@Override的功能类似。另外,由于默认方法不是抽象的,因此可以随意将自定义方法添加到函数接口中。需要记住的另一个要点是,如果一个接口声明一个抽象方法覆盖java.lang.Object其中的一个公共方法,那么这个方法也不会计入接口的抽象方法计数,因为接口的任何实现都将具有来自java.lang.Object的方法。

自定义函数接口

java.util.function包中有Function, BiFunction,但是没有TriFunction,假如我们需要这样一个函数接口,那么怎么办呢,
别着急,我们可以自定义一个,代码如下

        @FunctionalInterface
        public interface TriFunction<T, U, V, R> {
        
            R apply(T t, U u, V v);
        }
        
        Integer doSum(String s1, String s2) {
            return Integer.parseInt(s1) + Integer.parseInt(s2);
        }
        
        public void test() {
            
            TriFunction<Sum, String, String, Integer> t2 = Sum::doSum;
            
        }
结束语:

将lambda表达式设置为函数接口类型的设计决策,有助于java向下兼容。在某些情况下,创建自己的函数接口是合情合理的,但这么
做时应小心谨慎,仅在设计需要高度抽象或者现有的类库无法满足需要时,才考虑自定义函数接口。

参考引用

java.util.function接口文档
java8习惯用语-函数接口
java函数接口教程
java8函数式编程

猜你喜欢

转载自www.cnblogs.com/yuanbing1226/p/8994140.html