什么是函数式接口

  函数式接口是Java8引用的一个新特性,是一种特殊的接口:SAM类型的接口(Single Abstract Method)。但是它还是一个接口,只是有些特殊罢了。  函数式接口的出现主要是为了配合Java8的另一个新特性Lamdba表达式来使用。

  • 接口中只有一个抽象方法
  • 接口中面可以加一个注解@FunctionalInterface来检查接口中的方法是不是只有一个抽象方法
  • 在接口里面可以加入 默认方法静态方法
  • 函数式接口也可以继承,但是继承的时候,抽象方法必须一样
  • 函数式接口重写父类的的方法,并不会计入到自己的抽象方法中

自定义函数式接口

  1. //加入这个注解是为了检测接口中是否符合函数式接口的要求
  2. @FunctionalInterface
  3. public interface MyFunctionInterction {
  4. //唯一的抽象方法
  5. void absoluMethod();
  6. //重写Object的方法
  7. @Override
  8. String toString();
  9. //默认方法
  10. default void defaultMethod() {
  11. System.out.println("默认方法");
  12. }
  13. //静态方法
  14. static void stativMethod() {
  15. System.out.println("静态方法");
  16. }
  17. }

函数式接口的简单使用

  1. 里面的默认方法可以直接使用
  1. public class TestFunctionIntection {
  2. public static void main(String[] args) {
  3. TestFunctionIntection testFunctionIntection =
  4. new TestFunctionIntection();
  5. testFunctionIntection.test(
  6. //Lamdba表达式的简单使用
  7. () -> System.out.println("函数式接口里面的抽象方法"));
  8. }
  9. /**
  10. * 自己定义的一个方法,并使用自定义的一个消费类型的函数式接口
  11. * @param myFunctionInterction
  12. */
  13. public void test(MyFunctionInterction
  14. myFunctionInterction) {
  15. //函数式接口里面的抽象方法
  16. myFunctionInterction.absoluMethod();
  17. //默认方法
  18. myFunctionInterction.defaultMethod();
  19. //静态方法
  20. MyFunctionInterction.stativMethod();
  21. }
  22. }

java8里面自定义的四个核心的函数式接口

上面我自定义的一个接口,就是一个消费类型的函数式接口。其实这类接口在java.util.function里面有定义的,就是void Consumer< T >,消费类型接口,上面代码中的test方法里面的接口其实可以换成Consumer< T >接口,也可以用,下面主要就是介绍这四个函数式接口的简单使用。

下面是这四个核心接口的简单使用

  1. public class FunctionTest {
  2. //Consumer<T> 消费型接口
  3. @Test
  4. public void test1() {
  5. Consumer<String> consumer = (x) -> System.out.println(x);
  6. consumer.accept("消费型接口,没有返回值!");
  7. }
  8. //输出:消费型接口,没有返回值!
  9. //供给型接口
  10. @Test
  11. public void test2() {
  12. Supplier<String> supplier = () -> "主要的作用就是创建对象!";
  13. String s = supplier.get();
  14. System.out.println(s);
  15. }
  16. //输出:主要的作用就是创建对象!
  17. //函数型接口
  18. //Function<T,R> T 接收的参数,R 返回值类型
  19. @Test
  20. public void test3() {
  21. Function<Integer, String> function = (x) -> x + ":为String类型";
  22. String apply = function.apply(7);
  23. System.out.println(apply);
  24. }
  25. //输出:7:为String类型
  26. //断言型接口
  27. @Test
  28. public void test4() {
  29. Predicate<Integer> predicate = (x) -> x > 10;
  30. boolean test = predicate.test(11);
  31. System.out.println(test);
  32. }
  33. //输出:true
  34. }

Consumer 的应用

  1. //Consumer<T> 消费型接口
  2. @Test
  3. public void test1() {
  4. //定义一个消费型接口,只输出输入的内容
  5. Consumer<String> consumer = (x) -> System.out.println(x);
  6. //在输入的内容后面加上·--加上了默认方法·
  7. Consumer<String> consumer2 = (x) -> System.out.println(x + "--加上了默认方法");
  8. //执行顺序 先执行 accept 后面执行 addThen(然后)
  9. consumer.andThen(consumer2).accept("消费型接口,没有返回值!");
  10. }
  11. //输出:消费型接口,没有返回值 (accept输出的值)
  12. //输出:消费型接口,没有返回值 !--加上了默认方法 (addThen输出的值)

Consumer 的默认方法的源码:

  1. default Consumer<T> andThen(Consumer<? super T> after) {
  2. Objects.requireNonNull(after);
  3. return (T t) -> { accept(t); after.accept(t); };
  4. }

  其返回值这一句是重点,先是传入一个Consumer接口,然后返回一个Consumer接口,说明可以用表达式链,然后用这个特性可以把数据进一次进行加工。

  (T t) -> { accept(t); after.accept(t); };这一句,返回的顺序首先是调用抽象方法,然后再调用默认方法,说明这个默认方法只可以对数据进行再加工,不能再抽象方法前面。


Supplier 的应用

  1. //供给型接口,这个方法若以用在工厂方法中
  2. @Test
  3. public void test2() {
  4. //跟据一个字符串创建对象
  5. Supplier<String> supplier = () -> "主要的作用就是创建对象!";
  6. //获取一个对象
  7. String s = supplier.get();
  8. //获取两个以象
  9. String s1 = supplier.get();
  10. //两个对象内容一样
  11. System.out.println(s.equals(s1));
  12. System.out.println(s);
  13. //用方法引用的方式创建一个对象
  14. Supplier<SupplierTest> testSupplier = SupplierTest::new;
  15. //用new的方式创建一个对象
  16. Supplier<SupplierTest> supplierTestSupplier = () -> new SupplierTest("张三");
  17. //可以通过supplierTestSupplier 来获取一个对象,并且可以调用里面的方法
  18. String name = supplierTestSupplier.get().getName();
  19. System.out.println(name);
  20. }
  21. //输出:true
  22. //输出:主要的作用就是创建对象!
  23. //输出:张三

  Supplier< T >接口类型就有一个方法签名。T get()方法,没有默认方法。


Function< T,R > 的应用

  1. //默认主法addThen
  2. //函数型接口
  3. //Function<T,R> T 接收的参数,R 返回值类型
  4. @Test
  5. public void test3() {
  6. Function<String, String> f1 = (x) -> x +"+ ";
  7. Function<String, String> f2 = (x) -> x + "- ";
  8. //addThen(然后的意思)执行顺序先执行f1,并且把执行后的结果作为f2的输入参数
  9. String apply = f1.andThen(f2).apply("1");
  10. System.out.println(apply);
  11. }
  12. //输出:1+ -

addThen的源码:

  1. default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
  2. Objects.requireNonNull(before);
  3. return (V v) -> apply(before.apply(v));
  4. }

源码中最重要的一句

(V v) -> apply(before.apply(v)); 规定了执行顺序

  1. //默认主法compose
  2. //函数型接口
  3. //Function<T,R> T 接收的参数,R 返回值类型
  4. @Test
  5. public void test3() {
  6. Function<String, String> f1 = (x) -> x +"+ ";
  7. Function<String, String> f2 = (x) -> x + "- ";
  8. //addThen(然后的意思)执行顺序先执行f2,并且把执行后的结果作为f1的输入参数
  9. String apply = f1.compose(f2).apply("1");
  10. System.out.println(apply);
  11. }
  12. //输出:1- +

  三个默认方法,但是最后一个用的不多,这里也就不再介绍了。


Predicate< T > 的应用

  1. //默主方法negate 非
  2. //断言型接口
  3. @Test
  4. public void test4() {
  5. Predicate<Integer> predicate = (x) -> x > 10;
  6. boolean test = predicate.negate().test(11);
  7. System.out.println(test);
  8. }
  9. //输出:false
  1. //断言型接口
  2. //默认方法 or 和 and
  3. @Test
  4. public void test4() {
  5. Predicate<Integer> p1 = (x) -> x > 10;
  6. Predicate<Integer> p2 = (x) -> x < 5;
  7. //默认方法 or 或
  8. boolean test = p1.or(p2).test(3);
  9. //默认方法 and 且
  10. boolean test2 = p1.and(p2).test(3);
  11. System.out.println(test);
  12. System.out.println(test2);
  13. }
  14. //输出:true
  15. //输出:false

函数式接口的使用

  函数式接口的的使用,大部分都是在流操作里面进行,现在可以不太理解,但是可以在学习完流操作以后,再过来看,并且跟着写一遍。代码光看是没有用的。如果不写是不知道意思的。

参考的博客:浅浅的函数式接口


细节决定成败!

个人愚见,如有不对,恳请扶正!

Java8 新特性 函数式接口的更多相关文章

  1. Java8 新特性----函数式接口,以及和Lambda表达式的关系

    这里来讲解一下Java8 新特性中的函数式接口, 以及和Lambda 表达式的关系.看到过很多不少介绍Java8特性的文章,都会介绍到函数式接口和lambda表达式,但是都是分别介绍,没有将两者的关系 ...

  2. java8新特性-函数式接口详细讲解及案例

    一.函数式接口 1.1 概念 函数式接口在Java中是指:有且仅有一个抽象方法的接口.函数式接口,即适用于函数式编程场景的接口.而Java中的函数式编程体现就是Lambda,所以函数式接口就是可 以适 ...

  3. 【Java8新特性】接口中的默认方法和静态方法,你都掌握了吗?

    写在前面 在Java8之前的版本中,接口中只能声明常量和抽象方法,接口的实现类中必须实现接口中所有的抽象方法.而在Java8中,接口中可以声明默认方法和静态方法,本文,我们就一起探讨下接口中的默认方法 ...

  4. 【Java8新特性】- 接口中默认方法修饰为普通方法

    Java8新特性 - 接口中默认方法修饰为普通方法 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学 ...

  5. Java8的新特性--函数式接口

    目录 函数式接口 什么是函数式接口 函数式接口的使用 Java8内置的四大核心函数式接口 一.Consumer:消费型接口(void accept(T t)) 二.Supplier:供给型接口(T g ...

  6. Java8 新特性 —— 函数式编程

    本文部分摘录自 On Java 8 概述 通常,传递给方法的数据不同,结果也不同.同样的,如果我们希望方法被调用时的行为不同,该怎么做呢?结论是:只要能将代码传递给方法,那么就可以控制方法的行为. 说 ...

  7. Java8新特性_接口中的默认方法

    默认方法由来猜想 1. Collection接口.Collections公共类.  同是操作集合,为啥要搞俩?没必要.在接口中搞一些默认实现,一个接口即搞定了. 2. Java8支持Lambda表达式 ...

  8. Java8新特性之接口defualt,static方法

    简介 作用 Java8中接口引入了defualt,static两种方法提供默认实现,彻底打破了接口不能有默认实现的规定 static 让接口类似于工具类,提供一些静态方法 static方法不会被子类继 ...

  9. Java8新特性--函数式编程

    在jdk8中什么是函数式接口: 1.被@FunctionalInterface注解修饰的. 2.接口里边只有一个非default的方法. 满足以上2个条件的即为函数式接口,ps:即使一个接口没有被@F ...

随机推荐

  1. mysql 带外注入

    带外通道 有时候注入发现并没有回显,也不能利用时间盲注,那么就可以利用带外通道,也就是利用其他协议或者渠道,如http请求.DNS解析.SMB服务等将数据带出. payload SELECT LOAD ...

  2. web攻击日志分析之新手指

    0x00 前言 现实中可能会经常出现web日志当中出现一些被攻击的迹象,比如针对你的一个站点的URL进行SQL注入测试等等,这时候需要你从日志当中分析到底是个什么情况,如果非常严重的话,可能需要调查取 ...

  3. 各主流摄像头的rtsp地址格式

    海康威视rtsp://[username]:[password]@[ip]:[port]/[codec]/[channel]/[subtype]/av_stream说明:username: 用户名.例 ...

  4. Vue组件间通信6种方式

    摘要: 总有一款合适的通信方式. 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 组件是 vue.js 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的 ...

  5. JavaScript/JQuery自执行函数

    JavaScript中任何库与框架设计的第一个要点就是解决命名空间与变量污染的问题.jQuery就是利用了JavaScript函数作用域的特性,采用自执行函数包裹了自身的方法来解决这个问题.从jQue ...

  6. [PAT] 目录

    题号  PAT Basic  PAT Advaced  PAT Top 1001 害死人不偿命的(3n+1)猜想     1002 写出这个数     1003 我要通过!     1004 成绩排名 ...

  7. php模板模式(template design)

    没有写停止条件,所以会一直运行哟. <?php /* The template design pattern defines the program skeleton of an algorit ...

  8. CentOS6.10部署的Tomcat8.5启动后,浏览器访问不到的解决方法

    解决过程如下: 一.关闭 selinux 和 iptables 防火墙 二.查看 tomcat 是否在运行 ps aux |grep tomcat 三.查看端口情况 lsof -i:8080 查看后都 ...

  9. CEF3相关知识汇总(不断更新)

    CEF全称是Chromium Embedded Framework,它是Chromium的Content API的封装库. CEF官网地址:https://bitbucket.org/chromium ...

  10. Redash - 安装和初试

    前言 当业务成长到一定规模之后,会有许多想看各种不同类型报表的需求,如果单独做在后台,那么无疑会浪费前端和后端开发的时间.所以一直都有在寻找一款好用的BI工具.后面查了一下,市面上好用的一些非商业的B ...