java -- 函数式编程

打印 上一主题 下一主题

主题 951|帖子 951|积分 2853

函数式编程

面向对象过分强调“必须通过对象的形式来做事情”,而函数式思想则尽量忽略面向对象的复杂语法——强调做什么,而不是怎么做
有时只是为了做某事情而不得不创建一个对象,而传递一段代码才是我们真正的目的。
Lambda

Lambda是一个匿名函数,可以理解为一段可以传递的代码。
当需要启动一个线程去完成任务时, 通常会通过java.lang.Runnable接口来定义任务内容,并使用java.lang.Thread类来启动该线程
传统写法,代码如下:
  1. public class Demo {
  2.     public static void main(String[] args) {
  3.         new Thread(new Runnable() {
  4.             @Override
  5.             public void run() {
  6.                 System.out.println("多线程任务执行!");
  7.             }
  8.         }).start();
  9.     }
  10. }
复制代码
借助Java 8的全新语法,上述Runnable接口的匿名内部类写法可以通过更简单的Lambda表达式达到同样的效果:
  1. public class Demo04LambdaRunnable {
  2.     public static void main(String[] args) {
  3.         new Thread(() -> System.out.println("多线程任务执行!")).start(); // 启动线程
  4.     }
  5. }
复制代码
Lambda的优点  简化匿名内部类的使用,语法更加简单。
前提条件

必须是接口, 接口中有且只有一个抽象方法
有且仅有一个抽象方法的接口,称为函数式接口
格式

Lambda表达式的标准格式为:
  1. () -> {}
  2. () 参数列表,无参数留空
  3. -> 固定写法, 代表指向动作
  4. {} 方法体
复制代码
省略规则
在Lambda标准格式的基础上,使用省略写法的规则为:

  • 参数类型可省略
  • 如果只有一个参数 ()可以省略
  • 如果方法体只有一句话 return 大括号 分号都可省略, 但必须同时省略
  1. new Thread(() -> System.out.println("省略格式开启线程")).start();
复制代码
原理


  • 在匿名方法所在类中新增一个方法,方法体为Lambda表达式中的代码
  • 运行时形成一个新的类,并实现对应接口
  • 重写方法的方法体中调用匿名方法所在类中新生成的方法.
函数式接口

函数式接口在Java中是指:有且仅有一个抽象方法的接口
函数式接口,即适用于函数式编程场景的接口。而Java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用于Lambda使用的接口。
从应用层面来讲,Java中的Lambda可以看做是匿名内部类的简化格式,但是二者在原理上不同。
格式

只要确保接口中有且仅有一个抽象方法即可:
  1. 修饰符 interface 接口名称 {
  2.     public abstract 返回值类型 方法名称(可选参数信息);
  3. }
复制代码
由于接口当中抽象方法的public abstract是可以省略的,所以定义一个函数式接口很简单:
  1. public interface MyFunctionalInterface {
  2.     void myMethod();
  3. }
复制代码
@FunctionalInterface

@FunctionalInterface 该注解可用于一个接口的定义上:
  1. @FunctionalInterfacepublic interface MyFunctionalInterface {
  2.     void myMethod();
  3. }
复制代码
一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。不过,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口
常用函数式接口

Supplier接口

java.util.function.Supplier接口,它意味着"供给" , 对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象数据。
抽象方法:
T get() 用来获取一个泛型参数指定类型的对象数据
求数组元素最大值
使用Supplier接口作为方法参数类型,通过Lambda表达式求出int数组中的最大值
  1. public class supplierInterface {
  2.     public static void main(String[] args) {
  3.         int[] arr = {3,24,346,4,13};
  4.         method(() -> {
  5.             Arrays.sort(arr);
  6.             return arr[arr.length - 1];
  7.         });
  8.     }
  9.     public static void method(Supplier<Integer> s) {
  10.         Integer max = s.get();
  11.         System.out.println(max);
  12.     }
  13. }
复制代码
Consumer接口


java.util.function.Consumer 接口不生产数据,而是消费一个数据,其数据类型由泛型参数决定
抽象方法
void accept(T t),意为消费一个指定泛型的数据
默认方法
default Consumer andThen(Consumer
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

tsx81429

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表