剑指高效编程之函数编程
函数编程
购物车案例
创建下单商品类
/*** 下单商品信息对象*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Sku {//编号private Integer skuId;//名称private String skuName;//单价private Double skuPrice;//购买个数private Integer totalNum;//总价private Double totalPrice;//商品类型private Enum skuCategory;}
创建商品类型枚举
/*** 商品类型枚举类*/
@AllArgsConstructor
@NoArgsConstructor
public enum SkuCategoryEnum {CLOTHING(10,"服装类"),ELECTRONICS(20,"数码产品类"),SPORTS(30,"运动类"),BOOKS(40,"图书类");//商品类型编号private Integer code;//商品类型名称private String name;}
编写业务类
//构造商品信息
/*** 购物车服务类*/
public class CartService {/*** 加入到购物车的商品信息*/private static List<Sku> cartSkuList = new ArrayList<Sku>(){{add(new Sku(654032,"无人机",4999.00,1,4999.00,SkuCategoryEnum.ELECTRONICS));add(new Sku(642934,"VR一体机",2299.00,1,2999.00,SkuCategoryEnum.ELECTRONICS));add(new Sku(638482,"纯色衬衫",409.00,1,409.00,SkuCategoryEnum.CLOTHING));add(new Sku(621054,"跑步机",5999.00,1,5999.00,SkuCategoryEnum.SPORTS));add(new Sku(612350,"Java核心思想",129.00,1,129.00,SkuCategoryEnum.BOOKS));}};}
获得所有商品信息
/*** 返回商品信息列表* @return*/public static List<Sku> getCartSkuList (){return cartSkuList;}
需求一:找出购物车中所有的电子产品
/*** Version 1.0.0* 找出购物车中所有的电子产品* @param cartSkuList* @return*/public static List<Sku> filterElectronicsSkus(List<Sku> cartSkuList){List<Sku> result = new ArrayList<Sku>();for (Sku sku:cartSkuList) {//若果商品类型等于电子产品类if (sku.getSkuCategory().equals(SkuCategoryEnum.ELECTRONICS)){result.add(sku);}}return result;}
测试一
public class Version1Test {@Testpublic void filterElectronicsSkus(){//获取所有商品列表List<Sku> cartSkuList = CartService.getCartSkuList();//查找电子类商品List<Sku> skus = CartService.filterElectronicsSkus(cartSkuList);System.out.println(JSON.toJSONString(skus,true));}
}
需求二:根据传入的商品类型查找商品信息
/*** Version 2.0.0* 根据传入的商品类型查找商品信息* @return*/public static List<Sku> filterSkuByCategory(List<Sku> cartSkuList,SkuCategoryEnum skuCategoryEnum){List<Sku> result = new ArrayList<Sku>();for (Sku sku:cartSkuList) {if (skuCategoryEnum.equals(sku.getSkuCategory())){result.add(sku);}}return result;}
测试二
public class Version2Test {@Testpublic void filterSkuByCategory(){//查找购物车中图书类的商品集合List<Sku> cartSkuList = CartService.getCartSkuList();List<Sku> skus = CartService.filterSkuByCategory(cartSkuList, SkuCategoryEnum.BOOKS);System.out.println(JSON.toJSONString(skus,true));}
}
需求三:根据商品类型或商品总价来过滤商品类型
/*** Version 3.0.0* 根据商品类型或商品总价来过滤商品类型* @param cartSkuList* @param skuCategoryEnum* @param totalPrice* @param categoryOrPrice true:商品类型 false:商品总价* @return*/public static List<Sku> filterSkus(List<Sku> cartSkuList,SkuCategoryEnum skuCategoryEnum,Double totalPrice,Boolean categoryOrPrice){List<Sku> skuList = new ArrayList<Sku>();for (Sku sku:cartSkuList) {//如果根据商品类型进行判断,sku类型与输入类型比较//如果根据商品总价进行判断,sku总价与输入总价比较if ((categoryOrPrice && skuCategoryEnum.equals(sku.getSkuCategory())) || (!categoryOrPrice && sku.getTotalPrice() > totalPrice)){skuList.add(sku);}}return skuList;}
测试三
public class Version3Test {@Testpublic void filterSkus(){//根据商品总价进行过滤List<Sku> cartSkuList = CartService.getCartSkuList();List<Sku> skus = CartService.filterSkus(cartSkuList, null, 5000.00, false);System.out.println(JSON.toJSONString(skus,true));}
}
需求四:对需求三进行改进
创建SkuPredicate接口
/*** Sku选择谓词接口*/
public interface SkuPredicate {/*** 选择判断标准* @param sku* @return*/boolean test(Sku sku);
}
业务方法
/*** Version 4.0.0* 根据不同的Sku判断标准,对Sku列表进行过滤* @param cartSkuList* @param predicate - 不同的Sku判断标准策略* @return*/public static List<Sku> filterSkus(List<Sku> cartSkuList, SkuPredicate predicate){List<Sku> result = new ArrayList<Sku>();for (Sku sku:cartSkuList) {//根据不同的sku判断标准策略if (predicate.test(sku)){result.add(sku);}}return result;}
测试四
public class Version4Test {@Testpublic void filterSkus(){List<Sku> cartSkuList = CartService.getCartSkuList();//根据商品总价大于2000条件进行判断List<Sku> skus = CartService.filterSkus(cartSkuList, new SkuTotalPriceCategoryPredicate());System.out.println(JSON.toJSONString(skus,true));}
}
需求五:对需求四进行改进
创建SkuPredicate接口实现类
/*** 对Sku的商品类型为图书类的判断标准*/
public class SkuBooksCategoryPredicate implements SkuPredicate{@Overridepublic boolean test(Sku sku) {return SkuCategoryEnum.BOOKS.equals(sku.getSkuCategory());}
}
创建SkuPredicate接口实现类
/*** 对Sku的商品总价是否超出2000为判断标准*/
public class SkuTotalPriceCategoryPredicate implements SkuPredicate{@Overridepublic boolean test(Sku sku) {return sku.getTotalPrice() > 2000;}
}
测试五:使用匿名内部类
public class Version5Test {@Testpublic void filterSkus(){List<Sku> cartSkuList = CartService.getCartSkuList();//根据商品总价大于2000条件进行判断List<Sku> skus = CartService.filterSkus(cartSkuList, new SkuPredicate() {@Overridepublic boolean test(Sku sku) {return sku.getTotalPrice() > 1000;}});System.out.println(JSON.toJSONString(skus,true));}
}
需求六:对需求五进行改进
创建SkuPredicate接口实现类
测试六:使用lambda表达式
public class Version6Test {@Testpublic void filterSkus(){List<Sku> cartSkuList = CartService.getCartSkuList();//根据商品总价大于2000条件进行判断List<Sku> skus = CartService.filterSkus(cartSkuList,(Sku sku)->sku.getTotalPrice() > 2000);System.out.println(JSON.toJSONString(skus,true));}
}
以上就是函数编程的演化历史,根据需求的不断变化。
Lambda 表达式简介
- Java 8 引入函数式编程风格
- 可以理解为一种匿名函数的代替
- 通过行为参数化传递代码
Lambda 表达式的形式
- (parameters )-> expression
- (parameters )-> {statement;}
形式一:没有参数
()->System.out.println("Hello World");
形式二:只有一个参数
name->System.out.println("Hello World"+name);
形式三:没有参数,逻辑复杂
()->{System.out.println("Hello");System.out.println("World");}
形式四:包含两个参数方法
BinaryOperator<Long> functionAdd = (x,y) -> x+y;
Long result = functionAdd.apply(1L,2L);
形式五:对参数显示声明
BinaryOperator<Long> functionAdd = (Long x,Long y) -> x+y;
Long result = functionAdd.apply(1L,2L);
函数式接口
- 接口中只有一个抽象方法
- Java 8 的函数式接口朱注解: @FunctionInterface
- 函数式接口的抽象方法签名:函数描述符
实战案例
:自定义函数式接口
功能:实现读取本地文件后自定义处理逻辑功能
定义函数式接口
/*** 文件处理函数式接口*/
@FunctionalInterface
public interface FileConsumer {/*** 函数式接口抽象方法,* @param fileContent - 文件内容字符串*/void fileHandler(String fileContent);
}
宾编写业务类读取文件内容
/*** 文件服务类*/
public class FileService {/*** 通过 url 获取本地文件内容,调用函数式接口处理* @param url* @param fileConsumer*/public void fileHandle(String url,FileConsumer fileConsumer) throws IOException {//创建文件读取流BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(url)));//定义行变量和内容String line ;StringBuilder stringBuilder = new StringBuilder();while((line = bufferedReader.readLine()) != null){stringBuilder.append(line+"\n");}//调用函数式接口方法,将文件内容传递给lambda表达式,实现业务逻辑fileConsumer.fileHandler(stringBuilder.toString());}}
测试
public class FileServiceTest {@Testpublic void fileHandle() throws IOException {FileService fileService = new FileService();//通过lambda表达式打印文件容fileService.fileHandle("D:\\demo\\app\\src\\main\\java\\com\\ausware\\yaowenyu\\lambda\\file\\FileService.java",fileContent -> System.out.println(fileContent));}}
常用函数接口及使用
接口 | 参数 | 返回类型 | 描述 |
---|---|---|---|
Predicate< T > | T | boolean | 用于判别一个对象。比如求一个人是否为男性。也叫断定性接口 |
Consumer< T > | T | void | 用于接收一个对象进行处理但没有返回。比如接收一个人并打印他的名字。也叫消费型接口 |
Suppler< T > | None | T | 用提供一个对象。也叫供给型接口 |
Function<T,R> | T | R | 转换一个对象为不同类型的对象。 |
方法引用
方法引用:调用特定方法的Lambda表达式的一种快捷写法,可以让你重复使用现有的方法定义,并像Lambda表达式一样传递他们
指向静态方法的方法引用
指向任意类型实例方法的方法引用
指向现有对象的实例方法的方法引用
剑指高效编程之函数编程相关推荐
- 剑指高效编程之工具类
工具类 Google Guava 工具集简介 Guava工程包含了若干被Google的Java项目广泛依赖的核心库,例如∶集合.缓存﹑原生类型支持.并发库.通用注解.字符串处理.I/O等等. 所有这些 ...
- 牛客网剑指offer编程实践1-10题
牛客网剑指offer编程实践1-10题 1.二维数组中的查找 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这 ...
- 剑指offer编程题(JAVA实现)——第35题:数组中的逆序对
github https://github.com/JasonZhangCauc/JZOffer 剑指offer编程题(JAVA实现)--第35题:数组中的逆序对 题目描述 在数组中的两个数字,如果前 ...
- 剑指offer编程题(JAVA实现)——第38题:二叉树的深度
github https://github.com/JasonZhangCauc/JZOffer 剑指offer编程题(JAVA实现)--第38题:二叉树的深度 题目描述 输入一棵二叉树,求该树的深度 ...
- 牛客网 c++ 剑指Offer_编程题 第五题用两个栈实现队列
前言: 牛客网 c++ 剑指Offer_编程题 第五题用两个栈实现队列 题目: **这个题目不难,但是我感觉题目出得奇怪,刚开始没理解要干啥 我一个队列就能实现他要的功能为啥要两个 队列 queue ...
- 2020-8-26 剑指offer编程小哥令狐 075211
剑指offer~编程小哥令狐 一.数组类~ 03.数组中重复的数字 class Solution{public void swap(int[] nums,int i,int j){int temp=n ...
- 剑指Offer——编程题的Java实现(更新完毕……)
目录 二维数组中的查找 替换空格 从尾到头打印链表 重建二叉树 用两个栈实现队列 用两个队列实现一个栈 旋转数组的最小数字 斐波那契数列 跳台阶 变态跳台阶 矩形覆盖 二进制中1的个数 数值的整数次方 ...
- 三天刷完《剑指OFFER编程题》--Java版本实现(第三天)
正在更新中......... 剑指offer --Python版本的实现: 剑指offer(1/3)第一大部分 剑指offer(2/3)第二大部分 剑指offer(3/3)第三大部分 -------- ...
- 剑指Offer——编程题的Java实现
声明:我写这个的意图是我在看书的过程中,就我掌握的内容做一个笔记,没有抄袭的意图.再次说明一下,我找工作的过程中并不顺利,没有像那些牛人们拿到一大把的Offer,我只是希望通过我自己的努力,不断提高自 ...
最新文章
- 8. String to Integer
- 有关Non-cacheable,,Cacheable, non-shareable,inner-shareable,outer-shareable的理解
- py---------面向对象进阶
- 字符串的压缩【百度】
- ThinikPHP 前端URL模式
- 毕业两年的我--奋斗中的程序员
- ubuntu下安装psycopg2报错
- 右侧快速入口滑动时左侧跟着变化
- 5-4卷积神经网(上)5-5卷积神经网(下)
- 图片上传下载连接云服务器tomcat
- 计算机txt公式,完整word版本积分公式
- 快手火山美拍秒拍抖音映客yy小影视频批量下载毛驴保存去水印助手
- Photoshop定义画笔选区为空的原因
- Coverage [minx,miny,maxx,maxy] is [12, 4, 13, 6, 3], index [x,y,z] is [2, 5, 3]错误原因及其解决方式...
- 自定义View的OnMeasure问题
- 两个苹果手机共享步数_两个苹果手机同一个id数据是否共享?
- android12.0(S) Launcher3 导入 AndroidStudio 调试编译
- 多旋翼无人机仿真 rotors_simulator:roll pitch yawrate thrust 控制器
- python基础语法测评_Python基础语法测评(A1卷)
- html5 无障碍插件,HTML5 无障碍测试 Chromium 核心的 Edge 以满分砌低 Chrome!