Java函数式编程

Java函数式编程

匿名内置类

使用场景

Java作为一门面向对象的静态语言,其封装性能够屏蔽数据结构的细节,从而更加关注模块(功能)的功能性。其静态性也确保了Java强类型的特性。随着模块功能的提升,伴随而来的是复杂度的增加,代码的语义清晰依赖于开发人员的抽象(通用)和命名类或方法能力。尽管编程思想和设计模式能够促使编程风格趋于统一,然而大多数业务系统属于面向过程的方式(增删改查,输入输出),这与面向对象编程在一定程度上存在一些冲突。Java编程语言为了解决这个问题,引入了匿名内置类的方案

  • 经典使用场景

    • Java Event/Listener

    • Java Concurrent

    • Spring Template

基本特征

  • 无名称类

  • 声明位置(执行模块):

    ​ static block

      // Static 块
    static {
       new Runnable() {
           @Override
           public void run() {
          }
      };
    }

    ​ 实例block

      
    // 实例块
    {
       new Callable() {
           @Override
           public Object call() throws Exception {
               return null;
          }
      };
    }

    ​ 方法

      
    // 方法(类或实例)
    PropertyChangeListener listener = new PropertyChangeListener() {
       @Override
       public void propertyChange(PropertyChangeEvent evt) {
      }
    };

    ​ 构造器

      // 构造器
    public InnerClassDemo() {
       new Comparable(){

           @Override
           public int compareTo(Object o) {
               return 0;
          }
      };
    }
  • 并非特殊的类结构

    类全名称:$${package}.${declared_class}.${num}

基本特点

  • 基于多态(多数基于接口编程) 如Runnable,Callable

  • 实现类无需名称

  • 允许多个抽象方法

  
new KeyListener(){
   @Override
   public void keyTyped(KeyEvent e) {
  }
   @Override
   public void keyPressed(KeyEvent e) {
  }
   @Override
   public void keyReleased(KeyEvent e) {
  }
};

编程局限

  • 代码臃肿强制型约束 如:Runnable,Callable都指定了一类型

  • 接口方法升级

Lambda表达式

基本特点

  • ​ 流程编排清晰

  • ​ 函数类型编程

  • ​ 改善代码臃肿​ 兼容接口升级

实现手段

  • ​ @FunctionalInterface接口 声明函数式接口,并不一定要打这个注解,只要满足约束它就是函数式接口,有且只有一个抽象方法

Lambda语法

  
// 匿名类 传统写法
PropertyChangeListener listener = new PropertyChangeListener() {
   @Override
   public void propertyChange(PropertyChangeEvent evt) {
       println(evt);
  }
};

// Lambda 基本写法
PropertyChangeListener listener2 = evt -> {
   println(evt);
};

方法引用

  
// Lambda 简略写法
// PropertyChangeListener#propertyChange(PropertyChangeEvent)
// 属于有入参,没有返回,与 println(Object) 一样
PropertyChangeListener listener3 = LambdaDemo::println;

四种模式

SCFP = Supplier + Consumer + Function + Predicate

  
public class LambdaDemo {
   // SCFP = Supplier + Consumer + Function + Predicate
   // 四种模式(缺少 Action 模式)
   // Action 模式
   private static void showAction() {
       Runnable runnable = new Runnable() {
           @Override
           public void run() {
          }
      };
       Runnable runnable2 = () -> {
      };
       Runnable runnable3 = LambdaDemo::showConsumer;
  }
   // Supplier 模式
   private static void showSupplier() {
       String string = "Hello,World";
       Supplier<String> string2 = () -> "Hello,World";
       Supplier<String> string3 = () -> new Integer(2).toString();
  }
   // Consumer 模式
   private static void showConsumer() {
       // 匿名类 传统写法
       PropertyChangeListener listener = new PropertyChangeListener() {
           @Override
           public void propertyChange(PropertyChangeEvent evt) {
               println(evt);
          }
      };

       // Lambda 基本写法
       PropertyChangeListener listener2 = evt -> {
           println(evt);
      };

       // Lambda 简略写法
       // PropertyChangeListener#propertyChange(PropertyChangeEvent)
       // 属于有入参,没有返回,与 println(Object) 一样
       PropertyChangeListener listener3 = LambdaDemo::println;
  }

   // Function 模式
   private static void showFunction() {
       Function<String, Integer> f = LambdaDemo::compareTo;
  }

   private static Integer compareTo(String value) {
       return value.compareTo("Hello,World");
  }
   public static void main(String[] args) {
       Action a = () -> {
      };
  }
   private static void println(Object object) {
       System.out.println(object);
  }
   @FunctionalInterface
   public interface Action {
       void execute();
       default void doExecute() {
           execute();
      }
  }
   private static void stream() {
       Stream.of(1, 2, 3, 4, 5)
              .map(String::valueOf)
      ;
  }
}

编程局限

  • ​ 单一抽象方法

    ​ Lambda调试困难

    ​ Stream API 操作能力有限

原文地址:https://www.cnblogs.com/JavaUsername/p/13810641.html