Java 8 Function函数式接口及函数式接口实例

函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。

函数式接口可以被隐式转换为lambda表达式。

函数式接口可以现有的函数友好地支持 lambda。

介绍

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

java.lang.Runnable
java.util.concurrent.Callable
java.util.Comparator

等等...

使用方法

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

@FunctionalInterface
public interface Callable<V> {
  V call() throws Exception;
}

就这么简单。

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

// 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造成代码臃肿的,同时也可以把相同的业务逻辑抽象出函数接口,从而可以在多处代码重用。具体代码如下。

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的,而且还有以下几点好处

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

函数式接口实例

Predicate <T> 接口是一个函数式接口,它接受一个输入参数 T,返回一个布尔值结果。

该接口包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与,或,非)。

该接口用于测试对象是 true 或 false。

我们可以通过以下实例(Java8Tester.java)来了解函数式接口 Predicate <T> 的使用:

Java8Tester.java 文件
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Java8Tester {
  public static void main(String args[]){
   List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);

   // Predicate<Integer> predicate = n -> true
   // n 是一个参数传递到 Predicate 接口的 test 方法
   // n 如果存在则 test 方法返回 true
   System.out.println("输出所有数据:");
   // 传递参数 n
   eval(list, n->true);

   // Predicate<Integer> predicate1 = n -> n%2 == 0
   // n 是一个参数传递到 Predicate 接口的 test 方法
   // 如果 n%2 为 0 test 方法返回 true

   System.out.println("输出所有偶数:");
   eval(list, n-> n%2 == 0 );

   // Predicate<Integer> predicate2 = n -> n > 3
   // n 是一个参数传递到 Predicate 接口的 test 方法
   // 如果 n 大于 3 test 方法返回 true

   System.out.println("输出大于 3 的所有数字:");
   eval(list, n-> n > 3 );
  }

  public static void eval(List<Integer> list, Predicate<Integer> predicate) {
   for(Integer n: list) {

     if(predicate.test(n)) {
      System.out.println(n + " ");
     }
   }
  }
}

执行以上脚本,输出结果为:

$ javac Java8Tester.java
$ java Java8Tester

输出所有数据:

1
2
3
4
5
6
7
8
9

输出所有偶数:

2
4
6
8

输出大于 3 的所有数字:

4
5
6
7
8
9

总结

以上所述是小编给大家介绍的Java 8 Function函数式接口及函数式接口实例,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 浅析Java8新特性Lambda表达式和函数式接口

    什么是Lambda表达式,java8为什么使用Lambda表达式? "Lambda 表达式"(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数.我们可以把 Lambda表达式理解为是 一段可以传递的代码.最直观的是使用Lambda表达式之后不用再写大量的匿名内部类,简化代码,提高了代码的可读性. // 启动一个线程,不使用Lambda

  • 基于Java8 函数式接口理解及测试

    1. 函数式接口的理解 根据重构的思想,需要把容易变化的模块进行抽象并封装起来,从这个点来看,Java8新引入的函数式接口就是基于这个思想进行设计的. 2. 函数式接口定义 2.1 自定义如下 需要FunctionalInterface关键字显示声明: @FunctionalInterface public interface AppleInterface { public void test(); } 2.2 系统预定义 java.util.function.Consumer; java.ut

  • Java8简单了解Lambda表达式与函数式接口

    Java8被称作Java史上变化最大的一个版本.其中包含很多重要的新特性,最核心的就是增加了Lambda表达式和StreamAPI.这两者也可以结合在一起使用.首先来看下什么是Lambda表达式. 使用Lambda表达式不仅让代码变的简单.而且可读.最重要的是代码量也随之减少很多.然而,在某种程度上,这些功能在Scala等这些JVM语言里已经被广泛使用. 并不奇怪,Scala社区是难以置信的,因为许多Java 8里的内容看起来就像是从Scala里搬过来的.在某种程度上,Java 8的语法要比Sc

  • 实例详解Java8函数式接口

    以下我们继续深入Java8函数式编程模型 public class Test1 { public static void main(String[] args) { List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10); list.forEach(new Consumer<Integer>() { @Override public void accept(Integer integer) { System.out.prin

  • Java 8 Function函数式接口及函数式接口实例

    函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口. 函数式接口可以被隐式转换为lambda表达式. 函数式接口可以现有的函数友好地支持 lambda. 介绍 函数式接口其实就是一个抽象接口类,在Java 8之前已有的函数式接口有以下. java.lang.Runnable java.util.concurrent.Callable java.util.Comparator 等等... 使用方法 其实上述所说的接口类只需要使用Fun

  • Java8函数式接口java.util.function速查大全

    前言 Java 8中有很多新实用的特性,其中就有函数式接口.相信很多小伙伴都是第一次听到这个名词,下面进行函数式接口相关知识的学习. 函数式接口概念 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口. 函数式接口可以被隐式转换为 lambda 表达式. Java 8函数式接口可以对现有的函数友好地支持 lambda. 函数式接口组成 包含三部分: 1.一个括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数 2.一个箭头符号

  • 深入浅出理解Java Lambda表达式之四大核心函数式的用法与范例

    目录 1.四大核心函数式接口 1.1 Consumer<T> : 消费型接口 1.2 Supplier<T> : 供给型接口 1.3 Function<T, R> : 函数型接口 1.4 Predicate<T> : 断言型接口 2.方法引用 2.1 对象 :: 实例方法 2.2 类 :: 静态方法 2.3 类 :: 实例方法 3.构造器引用 4.数组引用 1.四大核心函数式接口 上一篇文章中说到了Lambda表达式中的基本语法,以及我们如何自定义函数式接口

  • Java并发教程之Callable和Future接口详解

    刚把Thread 的知识理了一遍. Runnable是一个接口,而Thread是Runnable的一个实现类. 所以也就有了之前创建线程的两种方法 继承Thread 实现Runnable 我们看一下新建线程的方法: 都是得传入一个Runnable对象(这句话很关键) 所以传入一个Runnble和Thread对象都行. 现在引入创建线程的第三种方法:Callable 为了实现 Runnable,需要实现不返回任何内容的 run()方法,而对于 Callable,需要实现在完成时返回结果的 call

  • Java接口和抽象类用法实例总结

    本文实例讲述了Java接口和抽象类用法.分享给大家供大家参考,具体如下: 接口 1 因为java不支持多重继承,所以有了接口,一个类只能继承一个父类,但可以实现多个接口,接口本身也可以继承多个接口. 2 接口里面的成员变量默认都是public static final类型的.必须被显示的初始化. 3 接口里面的方法默认都是public abstract类型的.隐式声明. 4 接口没有构造方法,不能被实例化. 5 接口不能实现另一个接口,但可以继承多个接口. 6 类如果实现了一个接口,那么必须实现

  • java比较器Comparable接口与Comaprator接口的深入分析

    java的比较器有两类,分别是Comparable接口和Comparator接口.在为对象数组进行排序时,比较器的作用非常明显,首先来讲解Comparable接口.让需要进行排序的对象实现Comparable接口,重写其中的compareTo(T o)方法,在其中定义排序规则,那么就可以直接调用java.util.Arrays.sort()来排序对象数组,实例如下: 复制代码 代码如下: class Student implements Comparable<Student>{    priv

  • 详解Java中接口的定义与实例代码

    Java中接口的定义详解 1.定义接口 使用interface来定义一个接口.接口定义同类的定义类似,也是分为接口的声明和接口体,其中接口体由常量定义和方法定义两部分组成.定义接口的基本格式如下: [修饰符] interface 接口名 [extends 父接口名列表]{ [public] [static] [final] 常量; [public] [abstract] 方法; } 修饰符:可选,用于指定接口的访问权限,可选值为public.如果省略则使用默认的访问权限. 接口名:必选参数,用于

  • java中抽象类、抽象方法、接口与实现接口实例详解

    前言 对于java中的抽象类,抽象方法,接口,实现接口等具体的概念就不在这里详细的说明了,网上书本都有很多解释,主要是我懒,下面通过一个例子来说明其中的精髓要点,能不能练成绝世武功,踏上封王之路,就看自己的的啦(不要误会,我指的只是我自己啦啦) 用接口实现一个简单的计算器 1.利用接口做参数,写个计算器,能完成+-*/运算 (1)定义一个接口Compute含有一个方法int computer(int n,int m); (2)设计四个类分别实现此接口,完成+-*/运算 (3)设计一个类UseCo

  • java公众平台通用接口工具类HttpConnectUtil实例代码

    实例如下: package com.common.util; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.URL; import

  • java以json格式向后台服务器接口发送请求的实例

    代码如下: import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import net.sf.json.JSONObject; public class InterfaceRequest {

随机推荐