前言:
📫 作者简介:小明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的机器语言,需要不断的适应硬件的更新,这样才能满足程序员的要求。