函数式接口

函数式接口详解:FunctionInterface接口

话不多说,先打开源码,查阅一番。寻得FunctionInterface接口

  1. package java.util.function;
  2. import java.util.Objects;
  3. /**
  4. * Represents a function that accepts one argument and produces a result.
  5. *
  6. * <p>This is a <a href="package-summary.html">functional interface</a>
  7. * whose functional method is {@link #apply(Object)}.
  8. *
  9. * @param <T> the type of the input to the function
  10. * @param <R> the type of the result of the function
  11. *
  12. * @since 1.8
  13. */
  14. @FunctionalInterface
  15. public interface Function<T, R> {
  16. /**
  17. * Applies this function to the given argument.
  18. *
  19. * @param t the function argument
  20. * @return the function result
  21. */
  22. R apply(T t);
  23. /**
  24. * Returns a composed function that first applies the {@code before}
  25. * function to its input, and then applies this function to the result.
  26. * If evaluation of either function throws an exception, it is relayed to
  27. * the caller of the composed function.
  28. *
  29. * @param <V> the type of input to the {@code before} function, and to the
  30. * composed function
  31. * @param before the function to apply before this function is applied
  32. * @return a composed function that first applies the {@code before}
  33. * function and then applies this function
  34. * @throws NullPointerException if before is null
  35. *
  36. * @see #andThen(Function)
  37. */
  38. default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
  39. Objects.requireNonNull(before);
  40. return (V v) -> apply(before.apply(v));
  41. }
  42. /**
  43. * Returns a composed function that first applies this function to
  44. * its input, and then applies the {@code after} function to the result.
  45. * If evaluation of either function throws an exception, it is relayed to
  46. * the caller of the composed function.
  47. *
  48. * @param <V> the type of output of the {@code after} function, and of the
  49. * composed function
  50. * @param after the function to apply after this function is applied
  51. * @return a composed function that first applies this function and then
  52. * applies the {@code after} function
  53. * @throws NullPointerException if after is null
  54. *
  55. * @see #compose(Function)
  56. */
  57. default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
  58. Objects.requireNonNull(after);
  59. return (T t) -> after.apply(apply(t));
  60. }
  61. /**
  62. * Returns a function that always returns its input argument.
  63. *
  64. * @param <T> the type of the input and output objects to the function
  65. * @return a function that always returns its input argument
  66. */
  67. static <T> Function<T, T> identity() {
  68. return t -> t;
  69. }
  70. }

函数式接口代码测试:FunctionTest

  1. public class FunctionTest {
  2. public static void main(String[] args) {
  3. FunctionTest test = new FunctionTest();
  4. // 传递行为,而不是传递值
  5. System.out.println(test.comput(1, value -> 2 * value));
  6. System.out.println(test.comput(2, value -> 5 + value));
  7. System.out.println(test.comput(3,Integer::intValue));
  8. System.out.println(test.convert(4,value -> value + "helloworld"));
  9. }
  10. public int comput(int a, Function<Integer, Integer> function) {
  11. //apply ,传递的是行为
  12. int result = function.apply(a);
  13. return result;
  14. }
  15. public String convert(int a, Function<Integer, String> function) {
  16. return function.apply(a);
  17. }
  18. // 对于之前只传递值的写法,几种行为就要定义几种写法。 现在可以使用上面的方式去 传递行为
  19. public int method1(int a) {
  20. return a + 1;
  21. }
  22. public int method2(int a) {
  23. return a * 5;
  24. }
  25. public int method3(int a) {
  26. return a * a;
  27. }
  28. }

高阶函数:如果一个函数接收一个函数作为参数,或者返回一个函数作为返回值,那么该函数就叫做高阶函数。函数式编程语言js等语言里面都支持大量的高阶函数,JAVA从1.8开始也开始支持高阶函数。

FunctionInterface接口中提供的方法详解

  1. apply
  2. compose (function组合)
  3. andThen
  4. identity

代码测试上述方法

  1. package java.util.function;
  2. import java.util.Objects;
  3. /**
  4. * Represents a function that accepts one argument and produces a result.
  5. *
  6. * <p>This is a <a href="package-summary.html">functional interface</a>
  7. * whose functional method is {@link #apply(Object)}.
  8. *
  9. * @param <T> the type of the input to the function
  10. * @param <R> the type of the result of the function
  11. *
  12. * @since 1.8
  13. */
  14. @FunctionalInterface
  15. public interface Function<T, R> {
  16. /**
  17. * Applies this function to the given argument.
  18. *
  19. * @param t the function argument
  20. * @return the function result
  21. */
  22. R apply(T t);
  23. /**
  24. * Returns a composed function that first applies the {@code before}
  25. * function to its input, and then applies this function to the result.
  26. * If evaluation of either function throws an exception, it is relayed to
  27. * the caller of the composed function.
  28. *
  29. * @param <V> the type of input to the {@code before} function, and to the
  30. * composed function
  31. * @param before the function to apply before this function is applied
  32. * @return a composed function that first applies the {@code before}
  33. * function and then applies this function
  34. * @throws NullPointerException if before is null
  35. * 先应用beforefunction,再应用实例的function
  36. 实际上:将两个function组合在一起了。先执行before方法,然后将处理的结果传递给当前对象的apply方法。实现了两个function的串联。既然实现了两个function的串联,就能实现多个函数的串联。
  37. * @see #andThen(Function)
  38. */
  39. default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
  40. Objects.requireNonNull(before);
  41. return (V v) -> apply(before.apply(v));
  42. }
  43. /**
  44. * Returns a composed function that first applies this function to
  45. * its input, and then applies the {@code after} function to the result.
  46. * If evaluation of either function throws an exception, it is relayed to
  47. * the caller of the composed function.
  48. *
  49. * @param <V> the type of output of the {@code after} function, and of the
  50. * composed function
  51. * @param after the function to apply after this function is applied
  52. * @return a composed function that first applies this function and then
  53. * applies the {@code after} function
  54. * @throws NullPointerException if after is null
  55. 和before函数相反,先应用this function,然后再使用after方法。 实现两个方法的串联。
  56. * @see #compose(Function)
  57. */
  58. default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
  59. Objects.requireNonNull(after);
  60. return (T t) -> after.apply(apply(t));
  61. }
  62. /**
  63. * Returns a function that always returns its input argument.
  64. *
  65. * @param <T> the type of the input and output objects to the function
  66. * @return a function that always returns its input argument
  67. */
  68. static <T> Function<T, T> identity() {
  69. return t -> t;
  70. }
  71. }
  • compose:

    先应用beforefunction,再应用实例的function

    实际上:将两个function组合在一起了。先执行before方法,然后将处理的结果传递给当前对象的apply方法。实现了两个function的串联。既然实现了两个function的串联,就能实现多个函数的串联。
  • andThen:

    和before函数相反,先应用this function,然后再使用after方法。 实现两个方法的串联。
  • identity:

    传入什么,返回什么。

这些方法都是很有价值的。

  1. /**
  2. * compose , andThen 方法的使用
  3. */
  4. public class FunctionTest2 {
  5. public static void main(String[] args) {
  6. FunctionTest2 test2 = new FunctionTest2();
  7. int compute = test2.compute(2, v -> v * 3, v -> v * v);//12
  8. int compute2 = test2.compute2(2, v -> v * 3, v -> v * v);//36
  9. System.out.println(compute);
  10. System.out.println(compute2);
  11. }
  12. public int compute(int a, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {
  13. return function1.compose(function2).apply(a);
  14. }
  15. public int compute2(int a, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {
  16. return function1.andThen(function2).apply(a);
  17. }
  18. }

BiFunction类详解

  1. package java.util.function;
  2. import java.util.Objects;
  3. /**
  4. * Represents a function that accepts two arguments and produces a result.
  5. * This is the two-arity specialization of {@link Function}.
  6. *
  7. * <p>This is a <a href="package-summary.html">functional interface</a>
  8. * whose functional method is {@link #apply(Object, Object)}.
  9. *
  10. * @param <T> the type of the first argument to the function
  11. * @param <U> the type of the second argument to the function
  12. * @param <R> the type of the result of the function
  13. *
  14. * @see Function
  15. * @since 1.8
  16. */
  17. @FunctionalInterface
  18. public interface BiFunction<T, U, R> {
  19. /**
  20. * Applies this function to the given arguments.
  21. *
  22. * @param t the first function argument
  23. * @param u the second function argument
  24. * @return the function result
  25. */
  26. R apply(T t, U u);
  27. /**
  28. * Returns a composed function that first applies this function to
  29. * its input, and then applies the {@code after} function to the result.
  30. * If evaluation of either function throws an exception, it is relayed to
  31. * the caller of the composed function.
  32. *
  33. * @param <V> the type of output of the {@code after} function, and of the
  34. * composed function
  35. * @param after the function to apply after this function is applied
  36. * @return a composed function that first applies this function and then
  37. * applies the {@code after} function
  38. * @throws NullPointerException if after is null
  39. */
  40. default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
  41. Objects.requireNonNull(after);
  42. return (T t, U u) -> after.apply(apply(t, u));
  43. }
  44. }

BiFunction类,双向接口类,提供了两个输入参数,一个输出参数

  1. //BiFunction类的使用。 有两个输入参数
  2. public int compute3(int a, int b, BiFunction<Integer, Integer, Integer> biFunction) {
  3. return biFunction.apply(a, b);
  4. }
  5. public int compute4(int a, int b, BiFunction<Integer, Integer, Integer> biFunction,Function<Integer,Integer> function) {
  6. return biFunction.andThen(function).apply(a,b);
  7. }
  8. //使用BiFunction来完成
  9. System.out.println(test2.compute3(1,2,(value1,value2)-> value1 + value2));
  10. System.out.println(test2.compute3(1,2,(value1,value2)-> value1 - value2));
  11. System.out.println(test2.compute3(1, 2, (value1, value2) -> value1 * value2));
  12. System.out.println(test2.compute3(1, 2, (value1, value2) -> value1 / value2));
  13. //使用BiFunction中的andThen.
  14. System.out.println(test2.compute4(2,3,(value1,value2)->value1+value2,value->value*value));

为什么BiFunction类中没有Compose方法呢?

倒推一下:因为如果有Compose方法,会先执行参数的Function。无论参数是Function还是BiFunction,返回值也都是一个值,然后就没办法再去执行BiFuntion.


使用lambda表达式解决简单的开发问题:

  1. 定义一个简单的Person类,然后使用lambda表达式解决一些问题
  2. public class Person {
  3. private String username;
  4. private int age;
  5. }
  1. package com.dawa.jdk8;
  2. import java.util.Arrays;
  3. import java.util.List;
  4. import java.util.function.BiFunction;
  5. import java.util.stream.Collectors;
  6. public class PersonTest {
  7. public static void main(String[] args) {
  8. Person person1 = new Person("zhangsan", 20);
  9. Person person2 = new Person("lisi", 30);
  10. Person person3 = new Person("wangwu", 40);
  11. List<Person> list = Arrays.asList(person1,person2,person3);
  12. PersonTest test = new PersonTest();
  13. //测试第一个方法。
  14. List<Person> list1 = test.getPersonByUsername("zhangsan", list);
  15. list1.forEach(person -> System.out.println(person.getUsername()));
  16. //测试第二种方法
  17. List<Person> personByAge = test.getPersonByAge(20, list);
  18. personByAge.forEach(person -> System.out.println(person.getAge()));
  19. //测试第三方法
  20. List<Person> peopleList = test.getPersonByArg(20, list,
  21. (age, personList) -> personList.stream().filter(p
  22. erson -> person.getAge() > age).collect(Collectors.toList()));
  23. peopleList.forEach(person -> System.out.println(person.getUsername()));
  24. }
  25. //使用lambda表达式定义一个 处理的方法
  26. //filter 方法,参数是一个Predicate 谓语
  27. //stream 提供了一个将流转换成集合的方法 collect(Collectors.toList())
  28. public List<Person> getPersonByUsername(String username, List<Person> personList) {
  29. return personList.stream().
  30. filter(person ->
  31. person.getUsername().equals("zhangsan")).collect(Collectors.toList());
  32. }
  33. //第二种方式,先直接使用lambda表达式将BiFunction定义好,然后直接将方法的两个参数传入到BiFunction.
  34. public List<Person> getPersonByAge(int age, List<Person> personList) {
  35. BiFunction<Integer, List<Person>, List<Person>> biFunction = (ageArg, Persons) -> {
  36. return Persons.stream().filter(person -> person.getAge() > ageArg).collect(Collectors.toList());
  37. };
  38. return biFunction.apply(age,personList);
  39. }
  40. //第三种方式,动作也让他自己传递。 函数式接口的好处。
  41. public List<Person> getPersonByArg(int age, List<Person> personList, BiFunction<Integer, List<Person>, List<Person>> biFunction) {
  42. return biFunction.apply(age, personList);
  43. }
  44. }

真谛:函数式接口,传递的是行为,而不是数据。

Predicate 类详解(谓词)

  1. package java.util.function;
  2. import java.util.Objects;
  3. /**
  4. * Represents a predicate (boolean-valued function) of one argument.
  5. *
  6. * <p>This is a <a href="package-summary.html">functional interface</a>
  7. * whose functional method is {@link #test(Object)}.
  8. *
  9. * @param <T> the type of the input to the predicate
  10. *
  11. * @since 1.8
  12. */
  13. @FunctionalInterface
  14. public interface Predicate<T> {
  15. /**
  16. * Evaluates this predicate on the given argument.
  17. *
  18. * @param t the input argument
  19. * @return {@code true} if the input argument matches the predicate,
  20. * otherwise {@code false}
  21. */
  22. boolean test(T t);
  23. /**
  24. * Returns a composed predicate that represents a short-circuiting logical
  25. * AND of this predicate and another. When evaluating the composed
  26. * predicate, if this predicate is {@code false}, then the {@code other}
  27. * predicate is not evaluated.
  28. *
  29. * <p>Any exceptions thrown during evaluation of either predicate are relayed
  30. * to the caller; if evaluation of this predicate throws an exception, the
  31. * {@code other} predicate will not be evaluated.
  32. *
  33. * @param other a predicate that will be logically-ANDed with this
  34. * predicate
  35. * @return a composed predicate that represents the short-circuiting logical
  36. * AND of this predicate and the {@code other} predicate
  37. * @throws NullPointerException if other is null
  38. */
  39. default Predicate<T> and(Predicate<? super T> other) {
  40. Objects.requireNonNull(other);
  41. return (t) -> test(t) && other.test(t);
  42. }
  43. /**
  44. * Returns a predicate that represents the logical negation of this
  45. * predicate.
  46. *
  47. * @return a predicate that represents the logical negation of this
  48. * predicate
  49. */
  50. default Predicate<T> negate() {
  51. return (t) -> !test(t);
  52. }
  53. /**
  54. * Returns a composed predicate that represents a short-circuiting logical
  55. * OR of this predicate and another. When evaluating the composed
  56. * predicate, if this predicate is {@code true}, then the {@code other}
  57. * predicate is not evaluated.
  58. *
  59. * <p>Any exceptions thrown during evaluation of either predicate are relayed
  60. * to the caller; if evaluation of this predicate throws an exception, the
  61. * {@code other} predicate will not be evaluated.
  62. *
  63. * @param other a predicate that will be logically-ORed with this
  64. * predicate
  65. * @return a composed predicate that represents the short-circuiting logical
  66. * OR of this predicate and the {@code other} predicate
  67. * @throws NullPointerException if other is null
  68. */
  69. default Predicate<T> or(Predicate<? super T> other) {
  70. Objects.requireNonNull(other);
  71. return (t) -> test(t) || other.test(t);
  72. }
  73. /**
  74. * Returns a predicate that tests if two arguments are equal according
  75. * to {@link Objects#equals(Object, Object)}.
  76. *
  77. * @param <T> the type of arguments to the predicate
  78. * @param targetRef the object reference with which to compare for equality,
  79. * which may be {@code null}
  80. * @return a predicate that tests if two arguments are equal according
  81. * to {@link Objects#equals(Object, Object)}
  82. */
  83. static <T> Predicate<T> isEqual(Object targetRef) {
  84. return (null == targetRef)
  85. ? Objects::isNull
  86. : object -> targetRef.equals(object);
  87. }
  88. }

默认调用:boolean test(T t)给定一个输入参数,判断是否满足条件。满足则返回true,不满足返回false。

测试案例:

  1. package com.dawa.jdk8;
  2. import java.util.function.Predicate;
  3. public class PreDicateTest {
  4. public static void main(String[] args) {
  5. Predicate<String> predicate = p -> p.length() > 5;
  6. System.out.println(predicate.test("hello"));
  7. }
  8. }

这个接口会在流stream里面得到大量的运用。上述案例在 stream的 filter()方法参数中使用。

到现在为止,Function包下的接口已经基础了两个了。

可是只是讲了几个特别重要的接口,其他的接口是没时间一个一个讲的。

这个时候我去看了一下源码,发现JAVA8底层源码,大量的使用函数接口来进行实现。

道阻且长。~ 加油。

2019年12月29日22:18:25。明天就要上班了,今晚早点休息。

JAVA8学习——深入浅出函数式接口FunctionInterface(学习过程)的更多相关文章

  1. JAVA8学习——深入浅出Lambda表达式(学习过程)

    JAVA8学习--深入浅出Lambda表达式(学习过程) lambda表达式: 我们为什么要用lambda表达式 在JAVA中,我们无法将函数作为参数传递给一个方法,也无法声明返回一个函数的方法. 在 ...

  2. Java8 学习笔记--函数式接口

    通过之前的函数式接口与lambda表达式的关系那篇文章,大家应该对函数式接口有了一定的了解了,在Java中它是lambda表达式的基础,没有函数式接口就没有办法使用lambda表达式. 函数式接口如此 ...

  3. Java8 学习笔记--函数式接口与lambda表达式的关系

    在java中,lambda表达式与函数式接口是不可分割的,都是结合起来使用的. 对于函数式接口,我们可以理解为只有一个抽象方法的接口,除此之外它和别的接口相比并没有什么特殊的地方.为了确保函数式接口的 ...

  4. java8新特性学习:函数式接口

    本文概要 什么是函数式接口? 如何定义函数式接口? 常用的函数式接口 函数式接口语法注意事项 总结 1. 什么是函数式接口? 函数式接口其实本质上还是一个接口,但是它是一种特殊的接口:SAM类型的接口 ...

  5. java基础---->java8中的函数式接口

    这里面简单的讲一下java8中的函数式接口,Function.Consumer.Predicate和Supplier. 函数式接口例子 一.Function:接受参数,有返回参数 package co ...

  6. Java8 新特性 函数式接口

    什么是函数式接口   函数式接口是Java8引用的一个新特性,是一种特殊的接口:SAM类型的接口(Single Abstract Method).但是它还是一个接口,只是有些特殊罢了.  函数式接口的 ...

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

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

  8. JAVA8学习——深入Comparator&Collector(学习过程)

    深入Comparator&Collector 从源码深入Comparator Comparator从Java1.2就出来了,但是在1.8的时候,又添加了大量的默认方法. compare() e ...

  9. java8中使用函数式接口

    使用函数式接口 Predicate @FunctionalInterface interface Predicate<T>{ boolean test(T t); } public sta ...

随机推荐

  1. 上传图片如何对图片进行压缩canvas

    前言:哈喽,朋友们,最近一直在马不停蹄地赶项目,很久没有写博客了.今天我们来看一下前端上传图片地时候如何对图片进行压缩 1.图片上传 我近期写项目都是使用的VUE,这里上传图片使用了Element-u ...

  2. @bzoj - 3749@ [POI2015] Łasuchy

    目录 @description@ @solution@ @version - 1@ @version - 2@ @accepted code@ @version - 1@ @version - 2@ ...

  3. Jmeter正则表达式提取多个值示例

    首先了解一下常用正则表达式的语法 \d           数字 \w          数字或者字母 .             可以匹配任意字符 星号*     表示任意个字符  +       ...

  4. Refs

    一.The ref callback attribute ref:reference,父组件引用子组件 组件并不是真实的 DOM节点,而是存在于内存之中的一种数据结构,叫做虚拟DOM.只有当它插入文档 ...

  5. phpstudy一直使用php5.6版本一直“”“报错应用程序无法正常启动0xc000007b”,亲测可行

    http://www.php.cn/xiazai/gongju/1351 vc9和vc11-vc14运行库 2018-01-26 来源/作者:php中文网 «» 下载次数:7808 工具简介: php ...

  6. SuperSocket 服务管理器 (ServerManager)

    什么 SuperSocket 服务管理器? SuperSocket 服务管理器是一个让你能够在客户中用图形化界面来管理和监控你的SuperSocket服务器程序的组件. 在服务器端配置服务器管理器 事 ...

  7. 【原生JS】键盘事件

    视频播放器音量调节效果. 效果图:“我很丑!~可是我有音乐和啤酒!~” HTML: <!DOCTYPE html> <html> <head> <meta c ...

  8. MVC插件式开发平台

    ---恢复内容开始--- 经过DyOS.BraveOS1.0再到BraveOS2.0,系统现在已经开发了下载. 我们的目标是,网页版操作系统,可以在线安装更新软件,并提供二次开发平台,提供基础的逻辑和 ...

  9. nano使用说明

    Main nano help text The nano editor is designed to emulate 仿真.模拟 the functionality and ease-of-use o ...

  10. H3C NAT ALG