赞
踩
1.什么是函数式编程
将业务逻辑细化,抽象,封装成一个个功能函数,并借助语言自带的高阶函数api,将整个业务流程转化为函数之间的相互调用,这就是函数式编程。
我们可以看到,函数式编程中,函数不仅直接调用,也可以当成参数被其他函数调用。因此,进一步,如果我们不仅想把函数当参数,还想传入值,所以再封装一下,函数和值封装后是什么。
函数->行为
值->属性
没错就是这就是对象
将业务逻辑细化,抽象,封装成一个个对象,并借助语言,库,组件,框架等,将整个业务流程转化为对象之间的相互调用,这就是面向对象编程。
因此,这么看来,函数式跟面向对象的思想其实都是一致的,即对逻辑的抽象与封装。
函数编程的最直接的表现,莫过于将函数作为数据自由传递,结合泛型推导能力,使代码表达能力获得飞一般的提升。
2.函数式编程优缺点
优点:
2.1.代码简洁,函数式编程写出的代码简洁且意图明确,比如使用stream接口让你告别for循环。
2.2.函数式编程不需要考虑"死锁"(deadlock),因为它不修改变量,所以根本不存在"锁"线程的问题。不必担心一个线程的数据,被另一个线程修改,所以可以很放心地把工作分摊到多个线程,部署"并发编程"(concurrency),从而使得编写并行程序如此简单,只需要调用一下parallel()方法即可。
2.3.函数式编程最大的好处是引用透明,即函数运行的结果只依赖于输入的参数,而不依赖于外部状态,因此,我们常常说函数式编程没有副作用
缺点:
所有的数据都是不可以改变的,严重占据运行资源,导致运行速度也不够快。
3.函数式接口
jdk8提供了一个函数式接口包java.util.function,里面有众多的函数式接口,这些接口有且只有一个未实现的方法的接口,一般通过FunctionalInterface这个注解来表明某个接口是一个函数式接口。函数式接口是Java支持函数式编程的基础,
关于函数接口,需要记住的就是两件事:
3.1.函数接口是行为的抽象;
3.2函数接口是数据转换器。
而其中最基础最常操作的有以下四个核心接口:
3.3.Function

Function<T,R>: 功能型接口,数据转换器
R apply(T) 方法接收一个 T 类型的对象,返回一个 R类型的对象,例如String.valueOf();
是一个单参数单返回值的行为接口;
提供了 apply, compose, andThen, identity 方法;
3.4.Consumer

consumer: 消费型接口,数据消费器
accept(T) 接收一个 T类型的对象,无返回值,通常用于设置T对象的值,例如System.out.printlnt
单参数无返回值的行为接口;
提供了 accept, andThen 方法;
3.5.Supplier

Supplier: 供给型接口,数据提供器
可以提供 T 类型对象,例如String的toUpperCase();
无参的构造器,提供了 get 方法;
3.6.Predicate

Predicate: 断言型接口,条件测试器
boolen test(T) 接收一个 T 类型的对象,返回布尔值,通常用于传递条件函数,例如String的equalsIgnoreCase();
单参数布尔值的条件性接口。
提供了 test (条件测试) , and-or- negate(与或非) 方法。
4.函数式编程的用例
package com.function; import java.util.function.Function; /** * @author luohaojie * @snice 2019-06-04 17:44 **/ public class FunctionTest { public static void main(String[] args) { Function<Integer, Integer> f = s -> s++; Function<Integer, Integer> g = s -> s * 2; System.out.println(f.apply(3)); /** * 下面表示在执行F时,先执行G,并且执行F时使用G的输出当作输入。 * 相当于以下代码: * Integer a = g.apply(1); * System.out.println(f.apply(a)); */ System.out.println(f.compose(g).apply(1)); /** * 表示执行F的Apply后使用其返回的值当作输入再执行G的Apply; * 相当于以下代码 * Integer a = f.apply(1); * System.out.println(g.apply(a)); */ System.out.println(f.andThen(g).apply(1)); /** * identity方法会返回一个不进行任何处理的Function,即输出与输入值相等; */ System.out.println(Function.identity().apply("a")); } } //打印 3 2 2 a package com.function; import java.util.ArrayList; import java.util.List; /** * @author luohaojie * @snice 2019-05-20 19:45 **/ public class ConsumerTest { @FunctionalInterface public interface Consumer { void accept(Object o); } public static void main(String[] args) { Consumer consumer = new Consumer() { @Override public void accept(Object o) { System.out.println(o); } }; consumer.accept("传统消费"); Consumer c2= (o) -> System.out.println(o); c2.accept("函数式消费"); } } //打印 传统消费 函数式消费 package com.function; import java.util.function.Predicate; /** * @author luohaojie * @snice 2019-06-04 17:50 **/ public class PredicateTest { public static void main(String [] args){ Predicate<String> p = o -> o.equals("test"); Predicate<String> g = o -> o.startsWith("t"); /** * negate: 用于对原来的Predicate做取反处理; * 如当调用p.test("test")为True时,调用p.negate().test("test")就会是False; */ System.out.println(p.negate().test("test")); /** * and: 针对同一输入值,多个Predicate均返回True时返回True,否则返回False; */ System.out.println(p.and(g).test("test")); /** * or: 针对同一输入值,多个Predicate只要有一个返回True则返回True,否则返回False */ System.out.println(p.or(g).test("ta")); } } //打印 false true true
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。