Java8 函数式接口

之前写了有关JDK8的Lambda表达式:java代码之美(1)---Java8 Lambda

函数式接口可以理解就是为Lambda服务的,它们组合在一起可以让你的代码看去更加简洁。

一、概念

1、什么是函数式接口

概念 所谓的函数式接口, 当然首先是一个接口, 然后就是在这个接口里面 只能有一个抽象方法

有关函数式接口,有个专门的注解叫:@FunctionalInterface。该注解主要特点有:

1、该注解只能标记在"有且仅有一个抽象方法"的接口上,表示函数式接口。
2、JDK8接口中的静态方法和默认方法,都不算是抽象方法。
3、接口默认继承 java.lang.Object,所以如果接口显示声明覆盖了Object中的方法,那么也不算抽象方法。
4、允许java.lang.Object中的public方法
5、该注解不是必须的,如果一个接口符合"函数式编程"定义,那么加不加该注解都没有影响。加上该注解能够 更好地让编译器进行检查,
如果编写的不是函数式接口,但是加上了@FunctionalInterface 那么编译器会报错。

2、示例

  1. 正确示例
/**
* 函数式接口注解
*/
@FunctionalInterface
public interface PersonInterface {
/**
* 1、仅有一个抽象方法
*/
void say(); /**
* 2、java.lang.Object中的方法不算
*/
@Override
boolean equals(Object var1); /**
* 3、java8 接口才可以有默认的方法实现 前提是方法名称必须使用default关键字修饰
*/
default void defaultMethod() {
System.out.println("haha");
} /**
* 4、静态方法
*/
static void staticMethod() {
}
}
  1. 错误示例

加上@FunctionInterface,就代表该接口是函数式接口,只能有一个抽象方法,如果有多个编译时就会直接报错。

3、为什么只能有一个抽象方法

其实这个问题很好去理解,上面说了函数式接口主要是为Lambda语法服务的,为了让代码看去更加简洁。

下面通过示例来说明

     public static void main(String[] args) {
//上面的接口 通过Lambda表达式重新 say方法
PersonInterface inter = () -> System.out.println("我说什么好呢?");
inter.say();
//控制台输出: 我说什么好呢?
}

通过 函数式接口 + Lambda表达式 让代码看去变的简洁,而这里的关键点在于:

 ()->{} 就是代表对say()方法的重写

如果你有个多个抽象方法, 那么()-> {} 这种写法,编译器就不知道这是重写的哪个方法了。所以这就是为什么只能有一个抽象方法的原因。

二、综合示例

这里再举一个综合示例,来方便理解它们。

自定义函数式接口

/**
* 自定义函数TestFunction,提供handler接口, 传入的是A,返回的是B
*/
@FunctionalInterface
public interface MyFunction<A, B> { /**
* @Description: 传入的是A 返回的是B
*/
B handler(A a, A a1);
}

Student对象

public class Student {
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age; //省略 set get toString 全参数构造函数 无参构造函数
}

测试类

   public static void main(String[] args) {
//1、求和 传入Integer返回Integer类型
MyFunction<Integer, Integer> myFunction1 = (x, y) -> {
//返回总和
return x + y;
};
Integer count = myFunction1.handler(5, 10);
System.out.println("输出总和为:" + count); //2、求和 传入Integer返回String类型
MyFunction<Integer, String> myFunction2 = (x, y) -> {
//返回总和
return x + " + " + y + " = " + (x + y);
};
System.out.println(myFunction2.handler(5, 10)); //3、对象处理 过滤对象
List<Student> students = Arrays.asList(new Student("小明", 3), new Student("小白", 13), new Student("小黄", 18));
MyFunction<Integer, List<Student>> myFunction3 = (x, y) -> {
//这里通过java8 的stream来过滤 年龄大于x 且小于y的对象
List<Student> studentList = students.stream().filter(student -> student.getAge() > x && student.getAge() < y).collect(Collectors.toList());
return studentList;
}; List<Student> list = myFunction3.handler(5, 15);
//遍历集合 输出对象
list.forEach(x -> System.out.println(x));
}

运行结果

从运行结果可以很明显看出,集合对象经过过滤只剩下一个满足条件的了。

你如果愿意有所作为,就必须有始有终。(24)

java代码之美(14)---Java8 函数式接口的更多相关文章

  1. java代码之美(16) ---Java8 Optional

    Java8 Optional 一句话介绍Optional类:使用JDK8的Optional类来防止NullPointerException(空指针异常)问题. 一.前言 在我们开放过程中,碰到的异常中 ...

  2. java代码之美(17) ---Java8 LocalDateTime

    Java8 LocalDateTime 在java8之前我们在处理时间的时候都是用的Date,但它其实有很明显的缺点. 1.我们也会对日期做一些操作,比如加几天.加几分,当月的最后一天等等.有些计算实 ...

  3. java代码(14) --Java8函数式接口

    Java8函数式接口 之前有关JDK8的Lambda表达式 Java代码(1)--Java8 Lambda 函数式接口可以理解就是为Lambda服务的,它们组合在一起可以让你的代码看去更加简洁 一.概 ...

  4. java代码之美(15)---Java8 Function、Consumer、Supplier

    Java8 Function.Consumer.Supplier 有关JDK8新特性之前写了三篇博客: 1.java代码之美(1)---Java8 Lambda 2.java代码之美(2)---Jav ...

  5. Java8新特性 - Java内置的四大核心函数式接口

    Java内置的四大核心函数式接口 Consumer:消费型接口 对类型为T的对象应用操作,包含方法:void accept(T t) public class TestLambda02 { publi ...

  6. java代码(15) ---java8 Function 、Consumer 、Supplier

    Java8 Function.Consumer.Supplier 有关JDK8新特性之前还有三篇博客: 1,java代码(1)---Java8 Lambda 2,java代码(2)---Java8 S ...

  7. 详解JAVA8函数式接口{全}

    1: 函数式接口 1.1 概念 1.2 格式 1.3@FunctionalInterface注解 1.4 调用自定义函数接口 2:函数式编程 2.1:lambda的延迟执行 2.2 使用Lambda作 ...

  8. Function接口 – Java8中java.util.function包下的函数式接口

    Introduction to Functional Interfaces – A concept recreated in Java 8 Any java developer around the ...

  9. java代码之美(1)---Lambda

    Lambda 一.概述 1.什么是Lambda表达式 Lambda 表达式是一种匿名函数,简单地说,它是没有声明的方法,也即没有访问修饰符.返回值声明和名字. 它可以写出更简洁.更灵活的代码.作为一种 ...

随机推荐

  1. 洛谷$P2153\ [SDOI2009]$ 晨跑 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 题目好长昂,,,大概概括下$QwQ$.就说有$n$个节点$m$条边,然后要求每次走的路径都不一样,问最多能走多少次,然后在次数最多的前提下问路径最短是多少$ ...

  2. 洛谷$P4001\ [ICPC-Beijing 2006]$狼抓兔子 网络流+对偶图

    正解:网络流+对偶图 解题报告: 传送门! $umm$日常看不懂题系列了$kk$.其实就是说,给定一个$n\cdot n$的网格图,求最小割$QwQ$ 然后网格图的话显然是个平面图,又看到数据范围$n ...

  3. 洛谷P1036 选数 题解 简单搜索/简单状态压缩枚举

    题目链接:https://www.luogu.com.cn/problem/P1036 题目描述 已知 \(n\) 个整数 \(x_1,x_2,-,x_n\) ,以及 \(1\) 个整数 \(k(k& ...

  4. 「学习笔记」ST表

    问题引入 先让我们看一个简单的问题,有N个元素,Q次操作,每次操作需要求出一段区间内的最大/小值. 这就是著名的RMQ问题. RMQ问题的解法有很多,如线段树.单调队列(某些情况下).ST表等.这里主 ...

  5. 「BZOJ1722」「Usaco2006 Mar」Milk Team Select产奶比赛 解题报告

    Milk Team Select 产奶比赛 Description Farmer John's N (\(1 \le N \le 500\)) cows are trying to select th ...

  6. golang编译之vendor机制

    Go 1.5引入了vendor 机制,但是需要手动设置环境变量 GO15VENDOREXPERIMENT= 1,Go编译器才能启用.从Go1.6起,,默认开启 vendor 目录查找,vendor 机 ...

  7. 力扣208——实现 Trie (前缀树)

    这道题主要是构造前缀树节点的数据结构,帮助解答问题. 原题 实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = ...

  8. Linux下Qt+CUDA调试并运行

    Qt与CUDA相结合具体的操作主要修改qt项目中的配置文件pro.下面以测试的项目为例. 因为这是一个测试案例,代码很简单,下面将这几个文件的代码贴出来,方面后面对应pro文件和Makefile文件中 ...

  9. 简单工厂模式(C++)

    #include <iostream> using namespace std; class Fruit { public : ; }; class Banana :public Frui ...

  10. linux下挂载硬盘出错的解决方法

    我的电脑是 Uuntu16.04 + win10 双系统,今天在Ubuntu中打开D盘时报错 Error mounting /dev/sda5 原因是D盘的格式是ntfs,在linux中会出现不识别的 ...