• 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 操作能力有限

  • 相关阅读:
    C#中如何禁止WindowsMediaPlayer双击全屏显示
    .NET中的泛型概述
    c# Windows服务管理
    C:Program不是内部或外部命令,也不是可运行的程序或批处理文件。
    Wireshark教程之二:Wireshark捕获数据分析
    Wireshark教程之一:认识Wireshark界面
    利用windows服务实现整点报时功能
    在windows服务中使用定时器
    flickity:支持触摸滑动,响应迅速的幻灯片轮播插件
    无法定位 Local Database Runtime 安装。请验证 SQL Server Express 是否正确安装以及本地数据库运行时功能是否已启用。
  • 原文地址:https://www.cnblogs.com/JavaUsername/p/13810641.html
Copyright © 2020-2023  润新知