在了解函数式编程前需要明白一个概念,函数式编程是一种编程范式。编程范式指的就是编程的套路。
面向过程、面向对象也是属于编程范式,既然都是编程套路所以各有高低,没有孰优孰劣,只有谁更合适。
那么函数式编程的套路是怎么样的呢?
函数式编程中的函数指的并不是编程语言中的函数(或方法),它指的是数学意义上的函数,即映射关系(如:y = f(x)),也就是 y 和 x 的对应关系。
所以当我们在讨论“函数式”时,我们其实是在说“像数学函数那样,接收一个或多个输入,生成一个或多个结果,并且没有副作用。
抽象的数学定义就不说了,直接上例子解释下什么是数学函数。
小学毕业的同学应该都知道一元一次方程吧,
如 [y = x + 10] 这样一个方程,任意一个x的值,都存在一个y的值与其对应。
这就是一个简单的一元函数。
为什么会有函数式编程?
先引入一下目前传统的编程方式:面向过程和面向对象
面向过程
面向过程是把解决问题的步骤分析出来,然后用函数把这些步骤实现,在一步一步的具体步骤中再按顺序调用函数。因为一套流水线或者流程就是用来解决一个问题,所以可扩展性极差
面向对象
面向对象是把要解决的问题分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个对象在整个解决问题的步骤中的属性和行为。
引入函数式编程
传统的面向过程和面向对象都会有一定的缺点。都有可能会对状态(变量或数据)进行更改,在多线程或分布式的场景下就涉及到数据一致性的问题(解决办法就是加锁或者应用分布式CAP理论实现某种程度上的数据一致性)。
如果说传统编程是对状态进行操作(修改),那么函数式编程语言就恰好相反,它不会修改状态,它只是描述计算的过程。所以在适当的场景利用好函数式编程这个工具,就能够使我们的工作更加有效。
函数式编程的应用
原生函数式编程的语言有:Haskell、Erlang。现在很多高级语言也在支持函数式编程,如java提供了一种函数式编程的特性,lambda表达式。
public static void main(String[] args) {
// 用匿名内部类的方式来创建线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("常规方式");
}
});
// 使用Lambda来创建线程
new Thread(() -> System.out.println("lamda表达式"));
}
通过上面简单的示例可以看出函数式编程很简洁,所以在适当的场景使用函数式编程可以极大地提供开发效率。
另外java的Stream流式操作就很典型,集合数据经过stream流式操作(过滤、排序等)后都是返回一个新的流,而不是更改原先的集合数据。
重要的是要在适当的场景使用函数式编程,千万不要为了用函数式编程而用函数式编程。