从面向过程出发到函数式编程(上篇)

面向过程编程(pop),面向对象编程(oop),函数式编程(fp) 1、概念 面向过程编程(procedure oriented Programming)(POP) 面向对象编程(object oriented programming)(OOP) 函数式编程(functional programming)(FP) 2、解释 面向过程编程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。 面向对象编程是... 阅读详情

小编

专注分享Java技术,坚持原创。你的关注和转发就是我们最好的动力。

前言

java8为我们引入的Lambda表达式、Stream ApI以及方法引用,它们为了java提供函数式编程的支持,虽然目前JDK已经出现到14的版本了,但是小编在工作中遇到一些员工中,对java的函数式编程并不有所了解,或者是不晓其原理。

今天我们就以一个对0~10间的累计为例子,从面向过程的编程方式开始,层层递进,演进到我们现在的函数式编程。

面向过程的累计

private static int sumInJava5(int size) {
    int sum = 0;
    // range方法是自定义的,获取1到10的集合
    List<Integer> values = range(1,size);
    for (Integer i : values) {
        sum += i;   
    }
    return sum;
}

这个例子使用到了jdk1.5的foreach语法,但其本身也是面向过程的,我们可以看出,加的操作是一步步的按照流程走,有先后之分。并不是通过调用对象的方法去进行累计。

说到这里,讲解一个疑惑,很多人只会用foreach语法,但是不知道集合和数组可以去使用foreach。其实是实现了Iterable的接口,提供了遍历的功能。

面向对象的累计

private static int sumInJava5Oop(int size, Sum sum) {
    int result = 0;
    // range方法是自定义的,获取1到10的集合
    List<Integer> values = range(1,size);
    for (Integer value : values) {
        result = sum.apply(result, value);
    }
    return result;
}


private interface Sum {
    /**
     * 加法运算
     * @param a 左值
     * @param b 右值
     * @return 返回值
     */
    int apply(int a, int b);
}


private static class SumImpl implements Sum{
    @Override
    public int apply(int a, int b) {
        return a + b;
    }
}

这个累加是通过一个Sum类型的对象。调用它的apply方法实现的,是一个面向对象的过程。

在使用这个计算方法过程中,无论是通过传入实现类还是匿名内部类,代码是很繁琐的,jdk的开发者们为了解决这个问题,引入了Lambda表达式、Stream ApI以及方法引用。

使用传统的方式与方法引用调用我们的方法

// 这是传统的
sum = sumInJava5Oop(10, new SumImpl());
// 这是方法引用
sum = sumInJava5Oop(10, SumImpl::apply);

 我们的第二行代码就是我们方法引用形式,使用到的操作符“::”,这个操作符把方法引用分成两边,左边是类名或者某个对象的引用,右边是方法名。

值得注意的是:由于类名引用需要方法是静态的,因此,java8提供了接口可以有静态方法的特性,在此之前的版本是没有的。

此外使用方法引用有一个重要的特点,虽然它作为我们方法的参数,但是并不需要是相同的类型和相同的方法名,只要保证相同的签名就行(方法返回值和方法的参数),如下面几种方式:

// 可以是实例对象的引用
sum = sumInJava5Oop(10, new SumImpl()::apply);
// 可以是完全不同类型对象方法名字
sum = sumInJava5Oop(10, OopDemo::calculate);

方法引用的格式

方法引用有以下四种类型

  • 引用静态方法 ContainingClass::staticMethodName 。

  • 引用某个对象的实例方法 containingObject::instanceMethodName

  • 引用某个类型的任意对象的实例方法 ContainingType::methodName

  • 引用构造方法 ClassName::new

这些都是java8提供新的编程语法支持的,它只要让编译器知道我们是方法参数、返回值以及在方法里面需要做什么就行。看到这里相信有不少人引发了另一个特性,没错就是我们的lambda表达式。

lambda表达式调用我们的累计方法

因为方法引用仅是一个方法实现的应用,在没有lambda表达式表达式的时候,我们选要在其他的地方编写我们的方法,而有了lambda表达式表达式以后,只需要在调用的位置写表达式就行:

sumInJava5Oop(10, (a,b) -> a+b);

注意:lambda表达式的主体仅包含一个表达式,且该表达式仅调用了一个已经存在的方法。方法引用的通用特性,方法引用所使用方法的入参和返回值与lambda表达式实现的函数式接口的入参和返回值一致。lambda可以看作是方法的实现。

函数式接口

我们可以发现,如果我们的Sum接口存在多个抽象方法,那么就不能用过lambda和方法引用进行传参操作。这是新语法提供高灵敏度的同时,也提供与之相应的保障。显然这种接口比较特殊,又有一个新的概念——函数式接口。

函数式接口的定义:

  • 一个接口有且只有一个抽象方法。

  • 函数式接口的实例可以通过 lambda 表达式、方法引用或者构造方法引用来创建。

创建函数式接口注意事项:

  • 如果我们在某个接口上声明了 @FunctionalInterface 注解,那么编译器就会按照函数式接口的定义来要求该接口。

  • 如果某个接口只有一个抽象方法,但我们并没有给该接口声明 @FunctionalInterface 注解,那么编译器依旧会将该接口看作是函数式接口。

  • 重写 Object 类里的方法不会导致函数式接口失效。

函数式接口可以有多个方法

虽然函数式接口的定义要求了我们一个接口有且只有一个抽象方法。但是java有提供接口的默认方法实现(default-method)来解决这个问题。

@FunctionalInterface
private interface Sum {
  // 抽象方法
  int apply(int a, int b);
  // default-method
  default int xx(int a, int b){
      return a*b;
  };
  // Object的方法
  String toString();
}

‍‍尽管Sum接口有3个方法,但是方法引用和lambda表达式走的还是我们的抽象方法。

使用default-method注意事项

  • 类实现接口方法,即如果接口声明了 default 方法,并且某类实现了该接口,那么 default 方法将会被继承。

  • 如果有一个类继承了两个不同接口的同名 default 方法,jvm 编译器是无法识别到底该使用哪个方法的,必须重写 default 方法。

  • 如果子类继承父类并实现接口,实现类的优先级比接口高。

专注分享Java技术,跟我一起学习吧

长按识别二维码关注

编程语言分哪些,它们有哪些差异 编程语言的分类维度很多(按范式用途执行方式等),核心差异集中在「设计目标、适用场景、语法风格、性能特性」上。下面先按核心分类逻辑梳理主流语言,再通过「关键维度对比」让差异更清晰。执行速度:编译型语言(C/C++/Rust/Go)> 虚拟机语言(Java/C#)> 解释型语言(Python/JS/PHP);开发效率:脚本语言(Python/JS/PHP)> 虚拟机语言(Java/C#)> 编译型系统语言(C/C++/Rust);内存安全。 阅读详情

相关推荐

函数式编程-Kotlin

什么是函数式编程?网上答案五花八门,有从历史开始阐述,有从Lambda演算开始,有从函数式编程和面向过程和面向对象的比较出发,有从函数式编程的特点闭包,高阶函数,柯里化(currying)开始,有从特定语言出发(JS,python,kotlin)开始讲。有的很吓人,有的很啰嗦,有的过于简单,有些不适合入门。我提取了前人的一些精华和自己的一些感悟斗胆尝试解释一下,希望对入门的同学有所帮助,就欣慰不已。

diangangqin的博客 940

Python从入门到实践:函数之两种编程思想(面向过程与函数式编程)

“面向过程”的重心就在过程二字,把一个大问题拆分成很多个小问题,然后依次执行每个小问题,这是一种流水线的、从上而下的过程。

weixin_43507744的博客 818

Buck-Boost电路实战:如何用LM2596模块快速搭建升降压电源(附元件选型指南)

本文详细介绍了如何使用LM2596模块快速搭建Buck-Boost升降压电路,包括硬件选型、电路搭建、示波器实测和进阶技巧。通过实测数据和避坑指南,帮助电子工程师解决电压不稳定、效率低下等常见问题,提升DC-DC变换器的设计水平。

weixin_30485379的博客 109

面向对象编程与面向过程编程和函数式编程之间的区别

是现在流行的编程范式(编程风格)。。随着面向对象编程的出现,面向过程编程已经逐渐退出了历史舞台,函数式编程目前还没有被程序员广泛接受,只能作为面向对象编程的补充。为了更好地理解面向对象编程,我们在本节中补充讲解面向过程编程和函数式编程,并且将面向对象编程与面向过程编程和函数式编程进行对比。

红军不怕远征难,万水千山只等闲 3290

基于Simulink的输入-输出线性化精确转矩控制

本文详细介绍了基于Simulink的永磁同步电机(PMSM)输入-输出线性化(IOL)精确转矩控制方法。针对传统解耦控制在非线性转矩特性下的局限性,通过建立PMSM非线性状态空间模型,设计IOL控制器将系统转化为线性输入-输出映射。文章包含系统原理推导、Simulink建模步骤、参数整定方法和仿真结果分析,验证了IOL在高动态、宽速域工况下的优越性能(转矩误差降低90%)。最后提出了工程实现要点和扩展应用方向,为开发高精度电机驱动系统提供了实用指导。

xiaoheshang_123的博客 304

嘉立创EDA vs Altium Designer:新手如何选择?从界面到实战全对比

本文全面对比了嘉立创EDA与Altium Designer(AD)两大PCB设计工具,从设计哲学、界面交互、封装库管理、设计规则引擎、协作功能到成本生态六大维度进行深入分析。嘉立创EDA以极简设计和云端协作为特色,适合学生和创客快速上手;而AD则凭借专业级精准控制,成为高端电子设计的行业标准。通过实战案例和详细对比表格,帮助新手根据项目需求选择合适的EDA工具。

weixin_30296405的博客 720

面向过程与函数式

1、面向过程 1.1、编程思想/范式 编程范式指的就是编程的套路,打个比方,如果把编程的过程比喻为练习武功, 那编程范式指的就是武林中的各种流派,而在编程的世界里常见的流派有:面向过 程、函数式、面向对象等, 1.2、面向过程的编程思想 面向过程核心是"过程"二字,过程即流程,指的是做事的步骤:先什么、再什么、 后干什么基于该思想编写程序就好比在设计一条流水线,即无论采用什么语言、无 论依据...

weixin_46466247的博客 663

保姆级教程:Halcon 3D点云匹配与差异分析避坑指南(从采样到可视化)

本文提供了一份详细的Halcon 3D点云匹配与差异分析实战指南,涵盖从模型准备到可视化的全流程。重点解析了STL文件读取单位误区、点云采样密度优化、表面模型创建技巧以及差异分析的专业手法,帮助用户避开常见陷阱,提升工业检测效率与精度。

weixin_33728268的博客 402

Python重点知识五:函数式编程(面向过程)

函数式编程

weixin_71370467的博客 191

【机器学习与数据挖掘实战 | 商务】案例03:基于k近邻算法的非侵入式电力负荷监测与分解的电力分析

本案例结合非侵入式电力负荷监测与分解的案例,重点介绍了在数据可视化的辅助下k近邻算法的应用。首先利用数据可视化寻找数据的特征,构建特征集合。然后构建k近邻模型,利用构建的特征集合训练模型,接着利用该模型对单一设备所属类别进行判定,最后计算实时用电量。

Morse_Chen的博客 2302

39、低功耗处理器性能评估与Cortex - M23/M33低功耗特性解析

本文深入解析了Cortex-M23和Cortex-M33处理器的低功耗特性及其性能评估方法。介绍了ULPMark、CoreMark、IoTMark-BLE和SecureMark-TLS等基准测试在能效评估中的应用,并详细阐述了处理器的睡眠模式、系统控制寄存器(SCR)配置、WFI/WFE指令、退出时睡眠、挂起时发送事件(SEVONPEND)以及唤醒中断控制器(WIC)等关键低功耗机制。结合状态保留技术,展示了如何通过芯片级设计大幅降低泄漏电流,实现高效能低功耗的物联网与嵌入式系统设计。

Pepper的专栏 129

从面向过程出发到函数式编程(下篇)

小编专注分享Java技术,坚持原创,你的关注和转发就是我们最好的动力。前言在上一个章节我们讲到Java程序的函数式编程是如何发展的而来的,那么本篇我们来说下Java为函数式编程提供哪些便...

ZeJava的博客 247

CDD数据库文件制作(二)——服务配置(0x27)

主要根据诊断调查表,针对0x27服务在CDD中的每一步配置给出详细介绍 1.会话切换配置 1.1.根据诊断调查表进行信息提取 1.2.子功能添加 1.2.1.Level1安全等级1创建 1.2.2.Level3安全等级3创建 1.2.3.安全等级名字查看与修改 1.3.会话切换信息提取(应用程序下) 1.4.会话转换配置(应用程序下) 1.5.会话切换信息提取(引导程序下) 1.6.会话转换配置(引导程序下) 2.安全等级配置信息提取 2.1.安全访问配置(level1) 2.2.安全访问配置(level2

LOVE135149的博客 2928

《Java 8 实战》第一季

《Java 8 实战》第一季1.函数式和命令式编程的差别-函数式编程

sinat_29484615的博客 372

FM20S用户手册--Linux系统启动卡制作及系统固化

评估板出厂时,默认提供一张配套的Micro SD卡,此卡为可正常使用的Linux系统 启动卡。评估板断电,将Linux系统启动卡插入评估板Micro SD卡槽,根据评估底板丝印将 启动方式选择拨码开关拨为1010(1-4).此档位为Micro SD启动模式。使用Linux 系统启动卡启动系统时,将使用此目录的BOOTbn文件启动FSBL和U-Boot。Linux系统启动卡制作时,已将固化系统的脚本文件mkemmcboot.sh拷贝至Linux系 统启动卡文件系统的"/opt/tools/"目录下。

创龙,嵌入式一体化解决方案商 301

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

面向过程(对象)与函数在基础语义上的差别以及对语义相对性的分析

为什么80%的码农都做不了架构师?>>> ...

weixin_34329187的博客 130

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

实现compose的五种思路

https://segmentfault.com/a/1190000011447164 好久没有更新了,最近学习的过程中一直在用联想的思维来去看问题,javascript是一门非常灵活的语言,集合了好多语言的特性和多种编程模式,对于compose的实现,就有非常多的思路,每一种思路都有自己的特点,实现之后,有种殊途同归的快感。下面就是我总结的实现compose函数的五种思路。 面向过程 ...

包磊磊的博客 2502

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

关于语言

自从入坑以来,七七八八的也用过了不少编程语言了。 一直都是处于学语法,写代码的程度。从来没有认真想过编程语言是什么。 也许是老了,有时候也不会闷头往前冲,而是停下来,静静的想一下,自己在写什么,为什么会这么写。   程序这种东西,最终的目的是让cpu来处理数据,只是因为过程太过复杂,慢慢的演变出来很多种语言。 [处理数据],很简单的一句话,那么就包括了[数据]和[处理]两个概念。复杂的...

flyforlove的专栏 158

基于自然语言的软件工程和程序设计(中)

这种问题是在行文时,分别描述两件事情或多件事情,这几件看上去毫无关系,只是由每一段的ABCD,abcd等不同的符号来标识,然而这些事情到最后却揭示的同一道理,或者是最后他们在同一场景汇聚,来构成了故事的结局。其实,我们不妨返璞归真,回到最初,让我们从语义出发,来讨论这形形色色的种种,你是否恍然大悟呢?这是每个人在做一件事情前的常规思维,编程时也是一样,我们在实现一个方法,或者在完成一个功能时,都会去想,应该先做什么,再做什么,然后我们会相应地把一个方法拆分成若干个子方法,这就是我们传统的面向过程的编程。

wDI77ts7y的博客 224

Python面向对象基础

面向对象 1.编程思想的转变 面向过程编程(穷人思想) 遇到问题马上相当的是解决问题的步骤和方案 工具:思路+基本语法 函数式编程(小资思想) 遇到问题马上想到的是是否已经存在一个函数具备解决问题的能力,如果有直接用,没有就造一个 工具:函数 面向对象编程(富豪思想) 遇到问题马上想到有没有一个对象具备这个功能,如果有直接用,没有就创建这个对象(创建对象还要看有没有类,没有类还要创建类) 工具 - 类和对象 2.类和对象 1.认识类和对象 类:类是具有相同功能和相同属性

m0_57864180的博客 154

函数式编程【1】——初识函数式编程

1.一段话理解函数式编程 首先说一下函数和方法的区别,简单的可以理解为同一个东西,都是一个执行块。前者是面向过程的叫法,后者是面向对象的叫法。所以说函数式编程某种程度上来说也可以理解为方法编程。而写过js的同学应该知道,在js中的函数是允许把另外一个函数作为自身参数的。后来仔细看了《java8实战》,谈一下自己的理解。函数式编程这个概念就是让我们用一种新的思维方式去写java。 2.举个栗子 我们先定义一个简单的People接口。 public interface People { void say

weixin_42931631的博客 244

函数式编程java要学好函数吗_开始学习函数式编程后对编程的一些新感受

最近开始学习函数式编程,打算深入进去,掌握函数式编程的思路。具体学习足迹可以看看 现代魔法学院的《编程范式篇》。以后关于技术类的东西,大部分都会整理成专题,章节,发布在学院中,而博客则回归更为轻松随意的状态。我们绝大多数程序员都是用命令式编程,因为学校教的编程就是命令式的,什么C、Java等等(当然他们也可以用函数式编程)。函数式编程和命令式编程不是一个相对应层次的概念。理论上,函数式编程的理论基...

weixin_34662154的博客 349

ansys参数化编程与命令手册_轻松玩转函数式编程

//每日前端夜话第406篇//正文共:3400字//预计阅读时间:10分钟最近和一些同学讨论了函数式编程,很多同学总觉得听起来很高大上,但用起来却无从下手。于是我抽时间捋了捋,将平时工作中用到的函数式编程案例和思想整理了出来,相信阅读本文后,大家都能快速上手函数式编程。函数式编程目前使用范围非常广,常用的框架,语言几乎都能看到它的身影。前端框架:react、vue 的 hoo...

weixin_39672396的博客 610

深入理解 Java 函数式编程系列 第 1 部分 函数式编程思想概论

前言在讨论函数式编程(Functional Programming)的具体内容之前,我们首先看一下函数式编程的含义。在维基百科上,函数式编程的定义如下:"函数式编程是一种编程范式...

小技术君 158

编程范式总结

1.什么是编程范式,编程范式都有哪些? 编程范式是一种方法论,用来指导你编写代码过程中的思路、规则、习惯和定式。是编码过程中一种纲领,起着引领的作用。编程范式和编程语言不同,有的范式只有少部分语言支持,有的范式很多语言都支持。有的语言只支持一种编程范式,有的语言支持多种范式。比如C++支持函数式编程,也支持面向对象编程、泛型编程。 常用的编程范式有:1.函数式编程2.面向过程编程3.面向对象编程4.泛型编程 2.编程范式的优缺点及支持的语言? 函数式编程是通过数学函数表达式的方式来避免状态和可.

yang1fei2的博客 1172
上一篇: 继续造轮子-MongoDB写日志
下一篇: 从面向过程出发到函数式编程(下篇)
新时代Java农民工
博客等级 码龄7年 16粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值