从Java8开始,我们就可以通过Java8中的StrameAPI与Lambda表达式实现函数式编程,可以让代码变得更加高效简洁。现在很多企业的生产代码已经开始使用Java8了,对于还没有使用过Java8进行的编程的朋友们可以好好的学习一下,我在企业中写Java8也有一段时间了,我想把我在实际开发中用到的一些场景与大家分享一下,大部分例子都来源于我开发项目中的实例。其中我开发中用得比较多的是,Optional,SteameAPI与lambda。本文是实战帖,不做过多理论分析,直接讲场景与应用。Java9已经出来一段时间了,我发现我周围的很多做开发的朋友对Java8中的一些新特性仍然不是很了解,也没在生产代码中使用过Java8,不过我相信,很快,大部分公司都会用上Java8的,我觉得Java8与Java5一样,是jdk历史上重要的一个版本更新,能给Java编程带来巨大变化的一个版本。
场景 1.数据类型转换直接上代码
//拿到所有的processNumber List<String> processNumbers = param.getListProcessNumbers().stream(). map(QueryStateData::getProcessNumber).collect(Collectors.toList());上面的代码的作用中把List<Object>,把其中我们需要的一个string字段变成List<String>,map是StringAPI中用来做数据类型转换的,QueryStateData::getProcessNumber是方法引用,作用与object->object.getProcessNumber();一样,collect是收集器,通过收集器,把流转换成我们想要的List<String>。
2.对List数据进行数据筛选 //获取paymentChange Optional<GaPaymentChange> changeOptional = listPaymentChange.stream().filter(p -> p.getTransferNo().equals(std.getProcessNumber())).findFirst(); if(changeOptional.isPresent()){ GaPaymentChange paymentChange = changeOptional.get(); }filter从名字上看,就知道是用来过数据过滤的,filter的函数式接口中需返回一个boolean值。findFirst是取其中的第一个,可以返回一个Optional对象。通过get方法我们很轻松的拿到了我们想要的结果。
3.Optional对象的应用java8中Optional的出现是为了减少空指针异常的。看代码应用:
BigDecimal bigAbmout = Optional.ofNullable(paymentChange.getPaymentChangeMoney()).orElseGet(() -> new BigDecimal("0")).setScale(2, BigDecimal.ROUND_HALF_UP);当ofNullable值为null时,我们可以给bigAbmout赋一个默认值。orElseGet的传参数是一个函数式接口,上面代码可以把它写成
lambda要返回一个对象。
orElse与orElseGet不同的是,它的参数直接是目标对象。
4.StreamAPI遍历对象 page.getRows().stream().forEach(x -> x.setOrderTime((DateUtils.dateFormat(x.getCreateTime(),DateUtils.DAT_SHORT_FORMATSS))));上面的代码就是简单的把集合对象中orderTime的值做一下转换。
5.快速找到集合中想要匹配数据 //是否存在增补单 boolean match = gaPaymentChangeDetailList.stream().anyMatch(detail -> GaConstants.SUPPLEMENT_BILL.equals(detail.getIsSupplementBill()));anyMatch配合lambda表达式可以在集合中快速找到我们想匹配的数据。
6.List中对象转换 List<Menu>menus= menuService.queryMenuList(query);List<MenuTreeVO> menuTrees = menus.stream().map(MenuTreeVO::new).collect(Collectors.toList());利用StreamAPI两行代码就把List<Menu>转成了 List<MenuTreeVO>,其中的map(MenuTreeVO::new)等价于map(menu->new MenuTreeVO(menu)),所以,实现的一个另一个细节,我重写了MenuTreeVO的构造方法:
public MenuTreeVO(Menu menu) { this.id = menu.getId(); this.pId = menu.getParentId(); this.name = menu.getName(); this.open = true; } 7.枚举中的应用枚举中我们通常会与一个静态方法通过code去获取它对应的枚举,没有用java8我们一般是通过for循环实现的,看看java8代码:
/** * 获取枚举 * * @param code * @return */ public static OrderStateEnum getEnum(Integer code) { return Stream.of(OrderStateEnum.values()).filter(e ->e.code.equals(code)).findFirst().orElse(null); } 8.lambda实现函数式接口我们原来代码中的遇到的函数式接口,我们就可以用lambda来代替,简单的来说,就是new接口的地方。比如MQ发消息,我们传统的做法:
jmsTemplate.send(new MessageCreator() { @Override public Message createMessage(Session session) throws JMSException { return session.createTextMessage(String.valueOf(id)); } });这个函数式接口可以用lambda一行代码轻松实现:
jmsTemplate.send(session -> session.createTextMessage(String.valueOf(id))); 8.去重、求和、最大值、最小值