函数式编程是一种结构化编程的范式,主要思想是把运算过程尽量写成系列嵌套的函数调用。函数编程的概念表述带有很抽象的感觉,可以基于案例看:
public class function01 { public static void main(string[] args) { // 运算:(x y)* c int x1 = 2 ; int y1 = 3 ; int c1 = 4 ; int sum1 = x1 y1 ; int res1 = sum1 * c1 ; system.out.println("res1 = " res1); }}
这里基于过程的方式做计算,上面的代码块着重在描述程序执行过程。
在看基于函数的方式解决方法:
public class function02 { public static void main(string[] args) { // 函数式计算 system.out.println("func01 = " func01(2,3,4)); } private static int func01 (int x,int y,int c){ return (x y)*c; }}
函数式编程的核心要素:传入参数,执行逻辑,返回值,也可以没有返回值。
函数式的编程风格侧重描述程序的执行逻辑,不是执行过程。
同上面计算过程相比,函数式编程也减少很多临时变量的创建,代码风格也变的简洁清楚。
在java语言中有函数式编程风格,但是java代码中没有函数的说法,而是称为:方法;
public class function03 { public static void main(string[] args) { func03 func03 = new func03(); func03.add(2); system.out.println(func03.res1); }}class func03 { public int res1 = 0 ; public void add (int a1){ this.res1 = a1 1 ; }}
类定义引用数据类型,类实例化后的对象可以调用类内部的方法和数据,这是最直观的感觉。
但是方法又有静态和非静态的区别,静态方法属于类所有,类实例化前即可使用。
非静态方法可以访问类中的任何成员变量和方法,并且必须是类实例化后的对象才可以调用。
lambda表达式也可称为闭包,是推动java8发布的最重要新特性,允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
这里就很鲜明的对比lambda表达式语法和传统用法。
public class lambda01 { interface lambdaopera { int operation(int a, int b); } public static void main(string[] args) { lambdaopera lambdaopera = new lambdaopera(){ @override public int operation(int a, int b) { return a * b ; } }; system.out.println(lambdaopera.operation(3,2)); lambdaopera lambdaopera01 = (int a, int b) -> a b; lambdaopera lambdaopera02 = (int a, int b) -> a - b; system.out.println(lambdaopera01.operation(3,2)); system.out.println(lambdaopera02.operation(3,2)); }}
在看一个直观的应用案例,基于lambda的方式创建线程,可以使代码变的更加简洁紧凑:
public class lambda02 { public static void main(string[] args) { new thread(new runnable() { @override public void run() { for (int i = 0; i < 2; i ) { system.out.println(i); } } }).start(); // 对比 lambda 方式 new thread(() -> { for (int i = 0; i < 2; i ) { system.out.println(i); } }).start(); }}
在看一下runnable接口的结构:
functionalinterface标记在接口上,表示该接口是函数式接口,并且该接口只包含一个抽象方法,
@functionalinterfacepublic interface runnable { public abstract void run();}
lambda表达式本身可以理解为就是一个接口的实现过程,这里runnable就是完整的lambda表达式声明:
public class lambda04 { public static void main(string[] args) { runnable runnable = () -> { system.out.println("run one..."); }; thread thread = new thread(runnable); thread.start(); }}
lambda表达式最直观的作用就是使得代码变得异常简洁,并且可以作为参数传递。
2、函数式接口lambda表达式虽然有很多优点,但是使用的时候需要定义一些接口用来完成编码,这样又使得表达式又变得重量级,java8自身已经提供几个常见的函数式接口。
function:输入一个参数,返回一个结果; consumer:输入一个参数,不返回结果; bifunction:输入两个参数,返回一个结果; biconsumer:输入两个参数,不返回任何结果;public class lambda05 { public static void main(string[] args) { function
如果面对更复杂的业务需求,可以自定义函数式接口去解决。
optional类是java函数式编程的应用,主要用来解决常见的空指针异常问题。
在java编程的开发中,很多地方都能常见空指针异常的抛出,如果想避免这个问题就要加入很多判断:
public class optional01 { public static void main(string[] args) { user user = new user(1,"hello") ; if (user != null){ if (user.getname() != null){ system.out.println(user.getname()); } } }}
为了确保程序不抛出空指针这种低级的错误,在程序中随处可以null的判断,代码显然冗余和繁杂。
2、optional应用基于optional类创建的对象可能包含空值和null值,也同样会抛出对应的异常:
public class optional02 { public static void main(string[] args) { // nosuchelementexception optional
所以在不明确对象的具体情况下,使用ofnullable()方法:
public class optional03 { public static void main(string[] args) { user user = new user(1,"say"); optional
这样看下来optional结合链式方法和lambda表达式就很大程度上简化了应用的代码量:
public class optional04 { public static void main(string[] args) { // 1、map转换方法 user user = new user(99, "java"); // user = null ; string name = optional.ofnullable(user) .map(u -> u.getname()).orelse("c "); system.out.println(name); // 2、过滤方法 optional
optional提供null处理的各种方法,可以简洁很多代码判断,但是在使用风格上和之前变化很大。
如果optional简化很多null的判断,那stream流的api则简化了很多集合的遍历判断,同样也是基于函数式编程。
上述为stream接口继承关系如图,同样提供一些特定接口和较大的包装接口,通过源码查看,可以看到和函数编程也是密切相关。
public class stream01 { public static void main(string[] args) { stream
stream与函数接口结合使用,函数接口又可以使用lambda表达式进行简化代码。在java8通过stream可以大量简化集合使用的代码复杂度。
public class stream02 { public static void main(string[] args) { // 1、转换stream list
在没有stream相关api之前,对于集合的操作和遍历都会产生大量的代码,通过stream相关api集合的函数式编程和lambda表达式的风格,简化集合很多操作。
github·地址
https://github.com/cicadasmile/java-base-parent
gitee·地址
https://gitee.com/cicadasmile/java-base-parent
以上就是java 函数式编程要点总结的详细内容,更多关于java 函数式编程的资料请关注软科小院其它相关文章!