首页 > 编程语言 >函数式编程

函数式编程

时间:2024-08-19 21:16:06浏览次数:11  
标签:函数 int void 编程 System static println public

函数式编程-Stream流

1. 概述

1.1 为什么学?

  • 能够看懂公司里的代码
  • 大数量下处理集合效率高
  • 代码可读性高
  • 消灭嵌套地狱

下面是没有使用函数式编程的代码:

//查询未成年作家的评分在70以上的书籍 由于洋流影响所以作家和书籍可能出现重复,需要进行去重
List<Book> bookList = new ArrayList<>();
Set<Book> uniqueBookValues = new HashSet<>();
Set<Author> uniqueAuthorValues = new HashSet<>();
for (Author author : authors) {
  if (uniqueAuthorValues.add(author)) {
    if (author.getAge() < 18) {
      List<Book> books = author.getBooks();
      for (Book book : books) {
        if (book.getScore() > 70) {
          if (uniqueBookValues.add(book)) {
            bookList.add(book);
          }
        }
      }
    }
  }
}
System.out.println(bookList);

下面是将上述代码改为函数式编程的代码:

List<Book> collect = authors.stream()
  .distinct()
  .filter(author -> author.getAge() < 18)
  .map(author -> author.getBooks())
  .flatMap(Collection::stream)
  .filter(book -> book.getScore() > 70)
  .distinct()
  .collect(Collectors.toList());
System.out.println(collect);

1.2 函数式编程思想

1.2.1 概念

面向对象思想需要关注用什么对象完成什么事情。而函数式编程思想就类似于我们数学中的函数。它主要关注的是对数据进行了什么操作。

1.2.2 优点

  • 代码简洁,开发快速
  • 接近自然语言,易于理解
  • 易于“并发编程”

2. Lambda表达式

2.1 概述

Lambda是JDK8中一个语法糖。他可以对某些匿名内部类的写法进行简化。它是函数式编程思想的一个重要体现。让我们不用关注是什么对象。而是更关注我们对数据进行了什么操作。

2.2 核心原则

可推导可省略

2.3 基本格式

(参数列表) -> {代码}

例一

我们在创建线程并启动时可以使用匿名内部类的写法:

new Thread(new Runnable() {
  @override
  public void run() {
    System.out.println("你知道吗 我比你想象的 更想在你身边");
  }
}).start();

如果匿名内部类是一个接口,并且当中只有一个抽象方法需要重写,可以对其进行简化。

修改后如下:

new Thread(() -> System.out.println("你知道吗 我比你想象的 更想在你身边")).start();

例二

现有方法定义如下,其中IntBinaryOperator是一个接口。先使用匿名内部类的写法调用该方法。

public static void main(String[] args) {
        int i = calculateNm(new IntBinaryOperator() {
            @Override
            public int applyAsInt(int left, int right) {
                return left + right;
            }
        });
        System.out.println(i);
}

public static int calculateNm(IntBinaryOperator operator) {
    int a = 10;
    int b = 20;
    return operator.applyAsInt(a, b);
}

Lambda写法:

public static void main(String[] args) {
        int i = calculateNm((left, right) -> left + right);
        System.out.println(i);
    }

    public static int calculateNm(IntBinaryOperator operator) {
        int a = 10;
        int b = 20;
        return operator.applyAsInt(a, b);
    }

例三

现有方法定义如下,其中IntPredicate是一个接口。先使用匿名内部类的写法调用该方法。

public static void main(String[] args) {
        printNum(new IntPredicate() {
            @Override
            public boolean test(int value) {
                return value % 2 == 0;
            }
        });
    }
public static void printNum(IntPredicate predicate) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        for (int i : arr) {
            if (predicate.test(i)){
                System.out.println(i);
            }
        }
    }

Lambda写法:

public static void main(String[] args) {
        printNum(value -> value % 2 == 0);
    }

例四

现有方法定义如下,其中Function是一个接口。先使用匿名内部类的写法调用该方法。

public static void main(String[] args) {
        Integer i = typeConver(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return Integer.valueOf(s);
            }
        });
        System.out.println(i);
    }
public static <R> R typeConver(Function<String, R> function) {
        String str = "12345";
        R result = function.apply(str);
        return result;
    }

Lambda写法:

public static void main(String[] args) {
    Integer i = typeConver(s -> Integer.valueOf(s));
    System.out.println(i);
}

例五

现有方法定义如下,其中IntConsumer是一个接口。先使用匿名内部类的写法调用该方法。

public static void main(String[] args) {
    foreachArr(new IntConsumer() {
        @Override
        public void accept(int value) {
            System.out.println(value);
        }
    });
}

public static void foreachArr(IntConsumer consumer) {
    int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    for (int i : arr) {
        consumer.accept(i);
    }
}

Lambda写法:

public static void main(String[] args) {
    foreachArr(value -> System.out.println(value));
}

2.4 省略规则

  • 参数类型可以省略
  • 方法体只有一句代码时大括号return和唯一一句代码的分号可以省略
  • 方法只有一个参数时小括号可以省略
  • 以上这些规则都记不住也可以省略不记

标签:函数,int,void,编程,System,static,println,public
From: https://www.cnblogs.com/xu1feng/p/18368143

相关文章

  • 【unix高级编程系列】信号
    引言以前对信号的理解,仅仅停留在main函数入口注册几个异常信号(SIGPIPE、SIGSEGV、SIGFPE)处理函数。当捕获到异常时,将进程的堆栈进行打印,方便排查、定位问题。这一类问题我认为是利用linux系统的异常信号机制,提高开发效率;后续随着工作经验的增长,linux的信号,还可以有其它用......
  • day03JS-函数
    1.什么是函数函数具有某种特定功能的代码块。函数其实本质也是一种数据,属于对象数据类型。2.为什么要有函数解决代码的冗余问题,形成代码复用。可以把整个代码项目,通过函数模块化。封装代码,让函数内部的代码对外部不可见。3.函数的组成函数的声明:function函数名(参数1,......
  • 字符函数与字符串函数详解
    ......
  • ctfshow-web入门-sql注入(web224-web230)文件类型注入、routines存储过程与函数状态、ha
    目录1、web2242、web2253、web2264、web2275、web2286、web2297、web2301、web224登录页面测了下没发现注入点存在robots.txt访问/pwdreset.php  ,是管理员密码重置的页面直接重置密码,这里以123456为例使用admin/123456登录 来到一个文件生成界......
  • 你是如何克服编程学习中的挫折感的?
            在编程学习的征途中,挫折感无疑是每位学习者必经的考验之一。它不仅考验着我们的技术能力,更磨砺着我们的意志与心态。面对这一系列的挑战,找到适合自己的应对策略显得尤为重要。以下是我个人在编程学习过程中如何克服挫折感、穿越Bug迷宫、保持冷静面对复杂算法......
  • 问题回答:你是如何克服编程学习中的挫折感的?
    你是如何克服编程学习中的挫折感的?编程学习之路上,挫折感就像一道道难以逾越的高墙,让许多人望而却步。然而,真正的编程高手都曾在这条路上跌倒过、迷茫过,却最终找到了突破的方法。你是如何在Bug的迷宫中找到出口的?面对复杂的算法时,你用什么方法让自己保持冷静?让我们一起分享那些......
  • 克服编程学习中的挫败感,收获满满的成就感
    文章目录一、前言二、克服编程学习过程中挫折感的方法2.1设定实际可行的目标2.2保持学习的新鲜感2.3理解学习过程是波动的2.4寻找学习伙伴或社群2.5反思和调整学习方法,学会复盘2.6保持好奇心和探索精神2.7接受失败并从中学习2.8寻求专业指导2.9庆祝小成就2.10......
  • 【Java 并发编程】(四) ThreadLocal 源码解读
     介绍每个Thread对象,内部有一个ThreadLocalMapthreadLocals,这是一个哈希表,底层是一个Node[]table;当在某个线程中调用ThreadLocal的set方法时,会使用Thread.currentThread获取当前先线程的thread对象,然后将ThreadLocal对象作为key,将set方法的参数作为value......
  • 农村高中生源转型期提升学生二次函数建模能力的课堂探究
       农村高中是位于乡镇地区的普通全日制高级中学,从区域发展来看,随着城市化进程的加快,学校生源逐年下降,农村高中学生的数学素养特别是解决问题的模型素养日益下降。本课题研究中的农村高中是指位一所位于农村的普通四星级高级中学。数学建模能力从量和型的侧面去考查实际问......
  • 如何利用sockserver模块编程实现客户端并发
    前面用sock模块写的服务端和客户端,存在一个大问题,就是当运行多个客户端的时候,必须等一个客户端运行结束,另一个客户端才能实现与服务端的交流,这显然不符合现实中的需求。有没有什么办法解决这个问题呢?有人说没有,屁话。当然有,这就需要用到一个sockserver的模块,用定义类继承类的方式......