java 函数式编程要点总结-pg电子游戏官网

热度:8℃ 发布时间:2022-01-20 13:08:21
目录一、函数式概念
二、函数与方法
三、jdk函数基础
1、lambda表达式
2、函数式接口
四、optional类
1、null判断
2、optional应用
五、stream流
六、源代码地址

一、函数式概念

函数式编程是一种结构化编程的范式,主要思想是把运算过程尽量写成系列嵌套的函数调用。函数编程的概念表述带有很抽象的感觉,可以基于案例看:

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 ;    }}

类定义引用数据类型,类实例化后的对象可以调用类内部的方法和数据,这是最直观的感觉。

但是方法又有静态和非静态的区别,静态方法属于类所有,类实例化前即可使用。

非静态方法可以访问类中的任何成员变量和方法,并且必须是类实例化后的对象才可以调用。

三、jdk函数基础

1、lambda表达式

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 function01 = x -> x * 2;        system.out.println(function01.apply(2));        bifunction function02 = (x, y) -> x * y;        system.out.println(function02.apply(2, 3));        consumer consumer01 = msg -> system.out.println("msg:" msg);        consumer01.accept("hello");        biconsumer consumer02 = (msg,i)                -> system.out.println(msg ":" i);        consumer02.accept("world",3);    }}

如果面对更复杂的业务需求,可以自定义函数式接口去解决。

四、optional类

1、null判断

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 optionaluser = optional.empty();        optionaluser.get();        // nullpointerexception        optional nullopt = optional.of(null);        nullopt.get();    }}

所以在不明确对象的具体情况下,使用ofnullable()方法:

public class optional03 {    public static void main(string[] args) {        user user = new user(1,"say");        optional optionaluser = optional.ofnullable(user);        if (optionaluser.ispresent()){            system.out.println(optionaluser.get().getname());        }        user user1 = null ;        user createuser = optional.ofnullable(user1).orelse(createuser());        system.out.println(createuser.getname());        user user2 = null ;        optional.ofnullable(user2).orelsethrow( ()                -> new runtimeexception());;    }    public static user createuser (){        return new user(2,"hello") ;    }}

这样看下来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 optuser01 = optional.ofnullable(user)                .filter(u -> u.getname() != null && u.getname().contains("c "));        // nosuchelementexception        system.out.println(optuser01.get().getname());    }}

optional提供null处理的各种方法,可以简洁很多代码判断,但是在使用风格上和之前变化很大。

五、stream流

如果optional简化很多null的判断,那stream流的api则简化了很多集合的遍历判断,同样也是基于函数式编程。

java 函数式编程要点总结

上述为stream接口继承关系如图,同样提供一些特定接口和较大的包装接口,通过源码查看,可以看到和函数编程也是密切相关。

public class stream01 {    public static void main(string[] args) {        stream stream = stream.of("hello", "");        stream.foreach(str -> system.out.print(str ";"));    }}

stream与函数接口结合使用,函数接口又可以使用lambda表达式进行简化代码。在java8通过stream可以大量简化集合使用的代码复杂度。

public class stream02 {    public static void main(string[] args) {        // 1、转换stream        list list = arrays.aslist("java ;", "c ;", "net;");        list.stream();        // 2、foreach操作        list.stream().foreach(system.out::print);        // 3、map映射,输出 3,4        intstream.rangeclosed(2,3).map(x->x 1).foreach(system.out::println);        // 4、filter过滤        list.stream().filter(str -> str.contains(" ")).foreach(system.out::print);        // 5、distinct去重        integer[] arr = new integer[]{3, 1, 3, 1, 2,4};        stream.of(arr).distinct().foreach(system.out::println);        // 6、sorted排序        stream.of(arr).sorted().foreach(system.out::println);        // 7、collect转换        list newlist = list.stream().filter(str -> str.contains(" "))                .collect(collectors.tolist());        newlist.stream().foreach(system.out::print);    }}

在没有stream相关api之前,对于集合的操作和遍历都会产生大量的代码,通过stream相关api集合的函数式编程和lambda表达式的风格,简化集合很多操作。

六、源代码地址

github·地址
https://github.com/cicadasmile/java-base-parent
gitee·地址
https://gitee.com/cicadasmile/java-base-parent

以上就是java 函数式编程要点总结的详细内容,更多关于java 函数式编程的资料请关注软科小院其它相关文章!

网友评论
评论
更多编程技术
  • 编程技术推荐
更多
最新软件下载
网站地图