函数式接口

概述:接口中只有一个抽象方法

下面介绍的可能很抽象,理解不了,至少在我看来单独的这几个借口是没有用的,跟最下面说的 Stream流一起用才会有效果

  • 函数式接口,即适用于函数式编程场景的接口。而Java中的函数式编程体现就是Lambda,所以函数式接口就是可

    以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,Java中的Lambda才能顺利地进行推导。

    备注:“语法糖”是指使用更加方便,但是原理不变的代码语法。例如在遍历集合时使用的for-each语法,其实

    底层的实现原理仍然是迭代器,这便是“语法糖”。从应用层面来讲,Java中的Lambda可以被当做是匿名内部

    类的“语法糖”,但是二者在原理上是不同的。

  • 格式:

    1. 只要确保接口中有且仅有一个抽象方法即可:

       修饰符 interface 接口名称 {
      public abstract 返回值类型 方法名称(可选参数信息);
      // 其他非抽象方法内容
      }
    2. @FunctionalInterface注解

      与@Override 注解的作用类似,Java 8中专门为函数式接口引入了一个新的注解: @FunctionalInterface 。该注

      解可用于一个接口的定义上,一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。需要注

      意的是,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样。

    3. 自定义函数式接口(前面已经写过,这就不重复写了)

      package com.wzlove.function;

      /**

      • 自定义函数式接口

      • 使用@FunctionalInterface可以说明该接口是函数式接口,但是不加,如果接口中只有一个抽象方法,这个接口也是函数式接口

      • 也就是说函数式接口不以注解的存在而存在

        */

        @FunctionalInterface

        public interface MyFunctionalInterface {

        public abstract void show();

        }

lambda表达式: (参数列表)->{代码}

lambda表达式(前面有篇文章说过,不详细说明)

有参数,有返回值的自定义函数式接口

    @FunctionalInterface
public interface Sumable {
int sum(int a, int b);
}

JDK1.8之后的某些函数式接口

supplier生产数据函数式接口

目的是生产数据.

目前好像看不出来有什么用,但是好像和jdk8的Stream流有关.,举个小例子

    package com.wzlove.supplier;

    import java.util.function.Supplier;

    /**
* 使用supplier函数式接口求数组的最大值
*/
public class ArrMaxValue { public static int getMaxValue(Supplier<Integer> sup){
return sup.get();
} public static void main(String[] args) {
// 创建数组
int[] arr = {100,20,50,30,99,101,-50}; int maxValue = getMaxValue(()->{
int max = arr[0];
for (int i : arr) {
if(i > max){
max = i;
}
}
return max;
}); System.out.println("数组中的最大值为:" + maxValue);
} }

Consumer消费数据函数式接口

这个方法是用来消费数据的,如何消费,消费规则自己定义.

java.util.function.Supplier 接口仅包含一个无参的方法: T get() 。用来获取一个泛型参数指定类型的对

象数据。由于这是一个函数式接口,这也就意味着对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象

数据。

package com.wzlove.comsumer;

import java.util.function.Consumer;

/**
* 使用Consumer函数式接口实现格式化输出
*/
public class ConsumerDemo2 { public static void printInfo(String[] strArr, Consumer<String> con1, Consumer<String> con2){ for (int i = 0; i < strArr.length; i++) {
con1.andThen(con2).accept(strArr[i]);
} } public static void main(String[] args) {
String[] strArr = {"迪丽热巴,女","郑爽,女","杨紫,女"};
printInfo(strArr,(message)->{
System.out.print("姓名:" + message.split(",")[0] + "。 ");
},(message)->{
System.out.println("性别:" + message.split(",")[1] + "。"); });
}
}

Predicate判断函数式接口

Predicate 接口中包含一个抽象方法: boolean test(T t) 。用于条件判断的场景

默认方法:

  • default Predicate and(Predicate<? super T> other) : 将两个Predicate 条件使用“与”逻辑连接起来实现“并且”的效果

  • default Predicate or(Predicate<? super T> other) : or 实现逻辑关系中的“或”

  • default Predicate negate() : 取反

    package com.wzlove.functionalinterface.predicate;

    import java.util.ArrayList;

    import java.util.function.Predicate;

    /**

    *

    */

    public class PredicateDemo2 {

      /**
    * 检查数组中的元素是否符合要求,满足要求加入List中并返回
    * @param arr 需要判断的数组
    * @param pre1 判断接口1,判断性别是否为女
    * @param pre2 判断接口2,判断姓名长度是否大于2
    * @return 集合
    */
    public static ArrayList<String> checkStar(String[] arr, Predicate<String> pre1, Predicate<String> pre2){
    // 创建集合
    ArrayList<String> list = new ArrayList<>();
    for (String s : arr) {
    if( pre1.and(pre2).test(s)){
    list.add(s);
    }
    }
    return list;
    } public static void main(String[] args) {
    // 创建数组
    String[] arr = {"迪丽热巴,女","杨洋,男","李溪芮,女","郑爽,女"}; // 调用方法(Lambda表达式可以简化)
    ArrayList<String> list = checkStar(arr,(str)->{
    return str.split(",")[1].equals("女");
    },(str)->{
    return str.split(",")[0].length() > 2;
    }); // 遍历集合
    for (String elem : list) {
    System.out.print(elem + " ");
    }
    }

    }

Function类型转换函数式接口

Function 接口中最主要的抽象方法为: R apply(T t) ,根据类型T的参数获取类型R的结果。

Function 接口中有一个默认的andThen 方法,用来进行组合操作。

package com.wzlove.functionalinterface.function;

import java.util.function.Function;

/**
*
*/
public class FunctionDemo2 { /**
* 将String分割,获得第二个元素,将数据转化为int,int数据加100,再将int转化为String
* @param str 转化的数据
* @param fun1 String -> String
* @param fun2 String -> Integer
* @param fun3 Integer -> String
* @return 最后的String
*/
public static String convert(String str,
Function<String,String> fun1,
Function<String, Integer> fun2,
Function<Integer,String> fun3){ return fun1.andThen(fun2).andThen(fun3).apply(str); } public static void main(String[] args) {
String str = convert("迪丽热巴,23",(s)->{
return s.split(",")[1];
},(s)->{
return Integer.parseInt(s) + 100;
},(s)->{
return String.valueOf(s);
});
System.out.println(str);
}
}

Java之函数式接口的更多相关文章

  1. Java 8 函数式接口

    函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口. 函数式接口可以被隐式转换为 lambda 表达式. Lambda 表达式和方法引用 ...

  2. Java 8 新特性-菜鸟教程 (3) -Java 8 函数式接口

    Java 8 函数式接口 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口. 函数式接口可以被隐式转换为lambda表达式. 函数式接 ...

  3. Java 8函数式接口functional interface的秘密

    Java 8函数式接口functional interface的秘密 2014年10月29日 17:52:55 西瓜可乐520 阅读数:3729   目录 [−] JDK 8之前已有的函数式接口 新定 ...

  4. Java常用函数式接口--Consumer接口andThen()方法使用案例(二)

    Java常用函数式接口--Consumer接口使用案例

  5. Java常用函数式接口--Predicate接口使用案例

    Java常用函数式接口--Predicate接口使用案例 该方法可以使用and来优化: 调用:

  6. Java之函数式接口@FunctionalInterface详解(附源码)

    Java之函数式接口@FunctionalInterface详解 函数式接口的定义 在java8中,满足下面任意一个条件的接口都是函数式接口: 1.被@FunctionalInterface注释的接口 ...

  7. JAVA 8 函数式接口 - Functional Interface

    什么是函数式接口(Functional Interface) 其实之前在讲Lambda表达式的时候提到过,所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法. 这种类型的接 ...

  8. JAVA 8 函数式接口--Consumer

    从JDK8开始java支持函数式编程,JDK也提供了几个常用的函数式接口,这篇主要介绍Consumer接口.文本介绍的顺序依次为: 源码介绍 使用实例 jdk内对Consumer的典型使用 扩展类介绍 ...

  9. Java 关于函数式接口与Lambda表达式之间的关系

    java是一种面向对象的语言,java中的一切都是对象,即数组,每个类创建的实例也是对象.在java中定义的函数或方法不可能完全独立,也不能将方法函数作为参数或返回值给实例. 在java7及以前,我们 ...

随机推荐

  1. Android系统的三种分屏显示模式

    Google在Android 7.0中引入了一个新特性——多窗口支持,允许用户一次在屏幕上打开两个应用.在手持设备上,两个应用可以在"分屏"模式中左右并排或上下并排显示.在电视设备 ...

  2. Android远程桌面助手(Build 0662)

    ARDC Build 0662, Jul 19, 2017 OPT: 1440*2560及以下分辨率设备,帧速能稳定在20帧~25帧 FIX: 拖拽文件的路径中包含空格的处理 ADD: 支持Ctrl+ ...

  3. 算法:数组中和为s的两个数字

    @问题 :题目描述输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们如果有多对数字的和等于S,输出两个数的乘积最小的. 输出描述:对应每个测试案例,输出两个数,小的先输出.@思路: 两个 ...

  4. matlab练习程序(对应点集配准的四元数法)

    这个算是ICP算法中的一个关键步骤,单独拿出来看一下. 算法流程如下: 1.首先得到同名点集P和X. 2.计算P和X的均值up和ux. 3.由P和X构造协方差矩阵sigma. 4.由协方差矩阵sigm ...

  5. momentjs的使用

    一.脚本引用 <script src="~/Scripts/moment.js"></script> <script src="~/Scri ...

  6. c/c++ 多线程 绕过mutex的保护

    多线程 绕过mutex的保护 mutex,能够解决线程安全的问题,但它不是万能的.下面的例子虽然使用了mutex,但是恶意注入了一个外部函数,导致把被mutex保护的双向链表,让一个外部的指针指向了, ...

  7. 5.4Python数据处理篇之Sympy系列(四)---微积分

    目录 目录 前言 (一)求导数-diff() 1.一阶求导-diff() 2.多阶求导-diff() 3.求偏导数-diff() (二)求积分-integrate() (三)求极限-limit() ( ...

  8. Elixir 简介

    概述 Elixir 是一种基于 Erlang 虚拟机的函数式,面向并行的通用语言, 它是一门通用语言,所以不仅可以用在擅长的高可用,高并发场景下,也可以用在 web 开发等场景下. Erlang 诞生 ...

  9. 《PHP扩展及核心》

    本文地址:http://www.cnblogs.com/aiweixiao/p/8202365.html 原文地址: 欢迎关注微信公众号  程序员的文娱情怀 一.主要内容: 1️⃣php扩展的概念和底 ...

  10. Django REST framework基础:分页

    DRF分页组件 为什么要使用分页 我们数据表中可能会有成千上万条数据,当我们访问某张表的所有数据时,我们不太可能需要一次把所有的数据都展示出来,因为数据量很大,对服务端的内存压力比较大还有就是网络传输 ...