【精通函数式编程】Java演变与函数式编程

举报
小明的混沌之路 发表于 2022/07/31 13:44:01 2022/07/31
【摘要】 Java8函数式编程实战开篇暴击,电商多重优惠核销代码初探


前言:

📫 作者简介:小明java问道之路,专注于研究计算机底层,就职于金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的设计和架构📫

🏆 Java领域优质创作者、阿里云专家博主、华为云享专家🏆

🔥 如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主哦


本文导读

本文导读为什么要学函数式编程(java高版本的特性)呢?主要有两点:一是、现在不管大还是中小企业多数使用8或以上版本的jdk包(笔者写此文的时候jdk已经到18了),生产代码会有很多8/11以及以上的新特性(比如lambda表达式、Stream流、函数式接口)等等,如果你不了解,那么项目里面的代码就看不懂,更无法完成工作;二是,无论是Spring源码还是JIT的一些新版本的源码,里面大量使用了Java8以上的新特性,如果还不懂Java8的话,未来源码解析对你来说根本不知道源码这么做的意图。


学什么东西?Lambda表达式、方法引用、StreamAPI、CollectionAPI、DSL(领域特定语言 domain-specific language)譬如Comparator、Collector、Optional类、Local…等时间API、CompletableFuture、反应式编程、函数式编程技巧和工程中的实例

一、函数式编程思想

首先函数式编程是思想也是一种概念,他是一种新的编程风格,更关注对数据进行什么操作,函数式编程的核心是把函数作为值(例如方法参数中的lambda表达式、Stream中输出流可能是下一方法的输入流),我们可以把他理解为一种设计模式和语法,可以更少的时间,编写更清晰更简洁的代码


二、浅尝java的变化

1、函数式编程是种新的编程模式,那什么是函数,在我们代码中函数通常指的是 方法,java8中新增了函数作为值(这个值是这么理解的,方法定义类,类可以实例化产生值,但是不管是方法还是类本身都不是值,java8将方法(函数)本身变成了值)


/**
 * 电商业务中有很多优惠信息,例如红包、平台券、商家券、满减、秒杀活动等等
 * 如果每个优惠写一个方法那么就不方便阅读和管理,我们可以用这种方式将代码扩展性做的很好
 */
public void writeOff(List<OrderInfo> orderList, Consumer<List<CouponInfo>> consumer) {
    List<CouponInfo> couponInfos = consume(orderList); // 每个优惠信息,由自己的实现类实现
    System.out.println("核销优惠信息"); 
    // 此处将结果保存
    consumer.accept(couponInfos);
}

/**
 * 假设为下单主流程
 */
public void submitOrder(List<OrderInfo> orderList) {
    Test test = new Test();
    test.writeOff(orderList, couponInfos -> { System.out.println("入库"); });
}

/**
 * 执行结果为:核销优惠信息 ->入库
 */
public static void main(String[] args) {
    Test test = new Test();
    test.submitOrder(new ArrayList<>());
}

执行结果为:

​2、把方法作为值来传递显然是有用简介的,但是类似于嵌套、循环、筛选这类的工具方法java8引入了匿名函数或Lambda,从而不需要定义方法就可以将函数处理


public static void main(String[] args) {
    Test test = new Test();
    List<OrderInfo> orderList = new ArrayList<>();
    test.transaction(orderList);
}

/**
 * 将大于10的订单组成一个哈希表
 */
private void transaction(List<OrderInfo> orderList) {
    Map<String, OrderInfo> orderInfoMap = new HashMap<>();
    for (OrderInfo orderInfo : orderList) {
        if (orderInfo.getOrderAmt().compareTo(BigDecimal.TEN) > 0) {
            orderInfoMap.put(orderInfo.getOrderId(), orderInfo);
        }
    }

    Map<String, OrderInfo> collect = orderList.stream().filter(orderInfo -> orderInfo.getOrderAmt().compareTo(BigDecimal.TEN) > 0)
            .collect(Collectors.toMap(OrderInfo::getOrderId, Function.identity()));
}


3、java处理多线程并发(Thread)在7之前,如果你的代码有反复的处理,你可能或有Thread或者Runnable进行多线程处理,在java8只有使用StreamAPI解决了集合中处理时没有多线程和模板。


三、语言的改变和硬件相关

我们大致了解java8的代码发生了什么变化之后,那我们思考为什么要变化?同时为什么java的版本变得越变越快?


现在新的计算机都是多核的,不仅仅有一个CPU(核、处理器),而java程序如果只利用其中一个核的话其他的核就浪费了,所以java8提供了新的编程风格,这样可以更好的配合计算机工作,于此同时go、PyThon等语言层出不穷,java需要保持自己的竞争力。


语言需要不断改进,因为底层好需要编译编器去编译成汇编语言执行,汇编语言也是不断变化的,例如现在RISC和CISC两大指令集,在不断变化,而汇编器去操作汇编将其转化为0101的机器语言,需要不断的适应硬件的更新,这样才能满足程序员的要求。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。