函数编程
购物车案例
Sku(商品对象信息)
package com.company.lambda.cart;
/**
* 下单的商品对象信息
*/
public class Sku {
//编号
private Integer skuId;
//商品名称
private String skuName;
//单价
private Double skuPrice;
//购买个数
private Integer totalNum;
//总价
private Double totalPrice;
//商品类别
private Enum skuCategory;
public Sku(Integer skuId, String skuName, Double skuPrice, Integer totalNum, Double totalPrice, Enum skuCategory) {
this.skuId = skuId;
this.skuName = skuName;
this.skuPrice = skuPrice;
this.totalNum = totalNum;
this.totalPrice = totalPrice;
this.skuCategory = skuCategory;
}
public Integer getSkuId() {
return skuId;
}
public String getSkuName() {
return skuName;
}
public Double getSkuPrice() {
return skuPrice;
}
public Integer getTotalNum() {
return totalNum;
}
public Double getTotalPrice() {
return totalPrice;
}
public Enum getSkuCategory() {
return skuCategory;
}
}
SkuCategoryEnum
package com.company.lambda.cart;
/**
* 商品类型的枚举
*/
public enum SkuCategoryEnum {
CLOTHING(10,"服装类"),
ELECTRONICS(20,"数码类"),
SPORTS(30, "运动类"),
BOOKS(40,"图书类");
// 商品类型编号
private Integer code;
// 商品类型名称
private String name;
SkuCategoryEnum(Integer code, String name) {
this.code = code;
this.name = name;
}
}
CartService
package com.company.lambda.cart;
import java.util.ArrayList;
import java.util.List;
/**
* 购物车服务类
*/
public class CartService {
// 加入到购物车里面的商品信息
private static List<Sku> cartSkuList = new ArrayList<>() {
{
add(new Sku(65266, "无人机", 4999.00,
1, 4999.00, SkuCategoryEnum.ELECTRONICS));
add(new Sku(65212, "VR", 2999.00,
1, 2999.00, SkuCategoryEnum.ELECTRONICS));
add(new Sku(65754, "浅色衬衫", 49.00,
3, 127.00, SkuCategoryEnum.CLOTHING));
add(new Sku(65354, "短袖", 495.00,
1, 495.00, SkuCategoryEnum.CLOTHING));
add(new Sku(65454, "长袖", 999.00,
3, 2997.00, SkuCategoryEnum.CLOTHING));
add(new Sku(65898, "网球", 19.00,
5, 95.00, SkuCategoryEnum.SPORTS));
add(new Sku(65242, "羽毛球", 99.00,
1, 99.00, SkuCategoryEnum.SPORTS));
add(new Sku(65414, "Java核心技术", 99.00,
1, 99.00, SkuCategoryEnum.BOOKS));
add(new Sku(65785, "Java编程思想", 80.00,
4, 320.00, SkuCategoryEnum.BOOKS));
}
};
/**
* 获取商品信息
*/
public static List<Sku> getCartSkuList() {
return cartSkuList;
}
}
业务逻辑(找出购物车属于电子产品的一类)
CartService
package com.company.lambda.cart;
import java.util.ArrayList;
import java.util.List;
/**
* 购物车服务类
*/
public class CartService {
...
/**
* Version 1.0
* 找出购物车里面的所有商品
* @param cartSkuList
* @return
*/
public static List<Sku> filterElectronicsSkus(List<Sku> cartSkuList) {
List<Sku> result = new ArrayList<Sku>();
for (Sku sku : cartSkuList) {
//如果商品类型 等于 电子类
if (SkuCategoryEnum.ELECTRONICS.equals(sku.getSkuCategory())) {
result.add(sku);
}
}
return result;
}
}
JSON依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
Test
@Test
public void filterElectronicsSkus(){
List<Sku> cartSkuList = CartService.getCartSkuList();
//查找购物车中数码类产品
List<Sku> result = CartService.filterElectronicsSkus(cartSkuList);
// 以JSON的格式展现出来
System.out.println(JSON.toJSONString(result,true));
}
根据传入商品类型参数,找出购物车中同种商品类型的商品列表
CartService/filterSkuByCategory
/**
* Version 2.0
* 根据传入商品类型参数,找出购物车中同种商品类型的商品列表
* @param cartSkuList
* @param category
* @return
*/
public static List<Sku> filterSkuByCategory(List<Sku> cartSkuList,SkuCategoryEnum category) {
List<Sku> result = new ArrayList<Sku>();
for (Sku sku : cartSkuList) {
//如果商品类型 等于 传入的商品类型
if (category.equals(sku.getSkuCategory())) {
result.add(sku);
}
}
return result;
}
Test
@Test
public void filterSkuByCategory(){
List<Sku> cartSkuList = CartService.getCartSkuList();
// 查找购物车中服装类商品集合
List<Sku> result = CartService.filterSkuByCategory(cartSkuList, SkuCategoryEnum.CLOTHING);
System.out.println(JSON.toJSONString(result,true));
}
支持通过商品类型或总价来过滤商品
CartService/filterSkus
/**
* Version.3.0
* 支持通过商品类型或总价来过滤商品
* @param cartSkuList
* @param category
* @param totalPrice
* @param categoryOrPrice -true:根据商品类型 false:根据商品总价
* @return
*/
public static List<Sku> filterSkus(List<Sku> cartSkuList, SkuCategoryEnum category, Double totalPrice, Boolean categoryOrPrice) {
List<Sku> result = new ArrayList<Sku>();
for (Sku sku : cartSkuList) {
//如果根据商品类型判断,sku类型与输入类型比较
//如果根据商品总价判断,sku总价与输入总价比较
if ((categoryOrPrice && category.equals(sku.getSkuCategory()))
||
(!categoryOrPrice && sku.getTotalPrice() > totalPrice)) {
result.add(sku);
}
}
return result;
}
Test
@Test
public void filterSkus(){
List<Sku> cartSkuList = CartService.getCartSkuList();
// 查找购物车中总价大于60块钱的商品
List<Sku> result = CartService.filterSkus(cartSkuList, null,660.00,false);
System.out.println(JSON.toJSONString(result,true));
// 查找购物车中服装类商品集合
List<Sku> result2 = CartService.filterSkus(cartSkuList, SkuCategoryEnum.CLOTHING,null,true);
System.out.println(JSON.toJSONString(result2,true));
}
通过Predicate来定义一个判断标准进行筛选
SkuPredicate
public interface SkuPredicate {
/**
* 选择判断标准
* 只有一个抽象接口
* @param sku
* @return
*/
boolean test(Sku sku);
}
filterSkus
/**
* Version 4.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判断标准策略,对Sku进行判断
if (predicate.test(sku)) {
result.add(sku);
}
}
return result;
}
Test
@Test
public void filterSkus2(){
List<Sku> cartSkuList = CartService.getCartSkuList();
//过滤商品总价大于2000的商品
List<Sku> result = CartService.filterSkus(cartSkuList, new SkuTotalPricePredicate());
System.out.println(JSON.toJSONString(result,true));
}
匿名类的使用
@Test
public void filterSkus3(){
List<Sku> cartSkuList = CartService.getCartSkuList();
//过滤商品总价大于2000的商品 使用匿名类(只使用一次)
List<Sku> result = CartService.filterSkus(cartSkuList, new SkuPredicate() {
@Override
public boolean test(Sku sku) {
return sku.getTotalPrice() > 2000;
}
});
System.out.println(JSON.toJSONString(result,true));
}
Lambda
@Test
public void filterSkusByLambda(){
List<Sku> cartSkuList = CartService.getCartSkuList();
//过滤商品总价大于2000的商品 使用Lambda表达式(只使用一次)
// List<Sku> result = CartService.filterSkus(cartSkuList, (Sku sku) -> sku.getTotalPrice() > 2000);
List<Sku> result = CartService.filterSkus(cartSkuList, sku -> sku.getTotalPrice() > 2000);
System.out.println(JSON.toJSONString(result,true));
}
- Java8引入的函数式编程风格
- 可以理解为一种匿名函数的代替
- 通过行为参数化传递代码
- (parameters) -> expression
- (parameters) -> { statement; }
// 形式一:没有参数
() -> System.out.println(" Hello World !" );
// 形式二:只有一个参数
name -> System.out.println(" Hello World from"+ 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);
函数式接口
- 接口中只有一个抽象方法
- Java8的函数式接口注解: @FunctionInterface
- 函数式接口的抽象方法签名:函数描述符
小测试
自定义函数式接口,实现读取本地文件后自定义处理逻辑功能。
FileConsumer
/**
* 文件处理函数式接口
*/
@FunctionalInterface
public interface FileConsumer {
/**
* 函数式接口抽象方法
* @param fileContent - 文件内容字符串
*/
void fileHander(String fileContent);
}
FileService
// 文件服务类
public class FileService {
/**
* 从url获取本地数据内容,调用函数式接口处理
*
* @param url
* @param fileConsumer
*/
public void fileHandle(String url, FileConsumer fileConsumer) {
// 创建文件读取流
try (BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(
new FileInputStream(url)));){
// 定义行变量和内容stringBuilder
String line;
StringBuilder stringBuilder = new StringBuilder();
// 循环读取文件内容
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line + "\n");
}
// 调用函数式接口方法,将文件内容传递给lambda表达式,实现业务逻辑
fileConsumer.fileHander(stringBuilder.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Test
public class FileServiceTest {
@Test
public void fileHangle(){
FileService fileService = new FileService();
fileService.fileHandle("D:\\develop_environment\\idea_place\\newJava2\\" +
"src\\test\\java\\com\\company\\test\\FileServiceTest.java",
fileContent -> System.out.println(fileContent));
}
}