demo场景描述
存在一个月份数值、一个金额数值、一个实体类,
1. 当月份数值为1时,给该实体的January属性赋予规定好的金额数值
2. 当月份数值为2时,给该实体的February属性赋予规定好的金额数值
....
11. 当月份数值为11时,给该实体的November属性赋予规定好的金额数值
12. 当月份数值为12时,给该实体的December属性赋予规定好的金额数值
正常情况下,使用if或switch流程控制语句判断月份数值,然后给对应月份的属性赋值即可。
这种方式会使业务代码中会出现大量的条件分支,不太简洁。
--可以尝试使用Function包下的BiConsumer类优化代码
具体实现
1. 先创建一个实体类,封装好月份金额属性
/**
* @author ShangHai
* @desc
*/
public class User {
/**
* 一月金额
*/
private BigDecimal januaryAmount;
/**
* 二月金额
*/
private BigDecimal februaryAmount;
/**
* 三月金额
*/
private BigDecimal marchAmount;
/**
* 四月金额
*/
private BigDecimal aprilAmount;
/**
* 五月金额
*/
private BigDecimal mayAmount;
/**
* 六月金额
*/
private BigDecimal juneAmount;
/**
* 七月金额
*/
private BigDecimal julyAmount;
/**
* 八月金额
*/
private BigDecimal augustAmount;
/**
* 九月金额
*/
private BigDecimal septemberAmount;
/**
* 十月金额
*/
private BigDecimal octoberAmount;
/**
* 十一月金额
*/
private BigDecimal novemberAmount;
...
(getter&setter)
}
2. 创建一个策略类
/**
* @author ShangHai
* @desc
*/
public class BiConsumerTest {
// 相当于策略列表
private static final Map<Integer, BiConsumer<User, BigDecimal>> BI_CONSUMER_MAP = new HashMap<>();
static {
// key是月份数值,value是实际执行的方法
BI_CONSUMER_MAP.put(CommonConstant.INT_1, User::setJanuaryAmount);
BI_CONSUMER_MAP.put(CommonConstant.INT_2, User::setFebruaryAmount);
BI_CONSUMER_MAP.put(CommonConstant.INT_3, User::setMarchAmount);
BI_CONSUMER_MAP.put(CommonConstant.INT_4, User::setAprilAmount);
BI_CONSUMER_MAP.put(CommonConstant.INT_5, User::setMayAmount);
BI_CONSUMER_MAP.put(CommonConstant.INT_6, User::setJuneAmount);
BI_CONSUMER_MAP.put(CommonConstant.INT_7, User::setJulyAmount);
BI_CONSUMER_MAP.put(CommonConstant.INT_8, User::setAugustAmount);
BI_CONSUMER_MAP.put(CommonConstant.INT_9, User::setSeptemberAmount);
BI_CONSUMER_MAP.put(CommonConstant.INT_10, User::setOctoberAmount);
BI_CONSUMER_MAP.put(CommonConstant.INT_11, User::setNovemberAmount);
BI_CONSUMER_MAP.put(CommonConstant.INT_12, User::setDecemberAmount);
}
}
3. main方法测试
public static void main(String[] args) {
User user = new User();
// 月份数值
int month = 2;
// 金额数值
BigDecimal bigDecimal = BigDecimal.valueOf(5.6);
// 传入策略列表,BiConsumer会根据传入的key,执行对应的赋值逻辑
BI_CONSUMER_MAP.get(month).accept(user, bigDecimal);
System.out.println(user);
}
4. 运行结果
5. 由结果可见,二月份金额属性成功赋予值,业务代码简洁不少【仅需一行代码】。
除了BiConsumer类,Function包内还有很多简单易用的封装类。
推荐常用的类如下:
Consumer<T>:传入一个参数T,无结果返回
BiConsumer<T, U>:传入两个参数T和U,无结果返回
Function<T, R>:传入一个参数T,返回一个自定义参数R
BiFunction<T, U, R>:传入两个参数T和U,返回一个自定义类型参数R
Predicate<T>:传入一个参数T,返回一个布尔类型值R 【此类可用作校验策略实现】
...
Consumer<T>策略应用
/**
* @author ShangHai
* @desc
*/
public class FunctionTest {
private static Map<Integer, Consumer<StringBuilder>> consumerMap = new HashMap<>();
static {
consumerMap.put(CommonConstant.INT_1, str -> str.append("strategy01"));
consumerMap.put(CommonConstant.INT_2, str -> str.append("strategy02"));
}
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder();
// 执行CommonConstant.INT_2策略,得到结果strategy02
consumerMap.get(CommonConstant.INT_2).accept(stringBuilder);
System.out.println(stringBuilder.toString());
}
}
输出结果:
strategy02
BiConsumer<T, U>策略应用
/**
* @author ShangHai
* @desc
*/
public class FunctionTest {
private static Map<Integer, BiConsumer<Integer, Integer>> biConsumerMap = new HashMap<>();
static {
biConsumerMap.put(CommonConstant.INT_1, FunctionTest::test01);
biConsumerMap.put(CommonConstant.INT_2, FunctionTest::test02);
}
private static void test01(int a, int b){
System.out.println(a+b);
}
private static void test02(int a, int b){
System.out.println(a-b);
}
public static void main(String[] args) {
// 执行CommonConstant.INT_2策略,程序执行test02方法,得到7
biConsumerMap.get(CommonConstant.INT_2).accept(12, 5);
}
}
输出结果:
7
Function<T, R>策略应用
/**
* @author ShangHai
* @desc
*/
public class FunctionTest {
private static Map<Integer, Function<StringBuilder, String>> functionMap = new HashMap<>();
static {
functionMap.put(CommonConstant.INT_1, FunctionTest::test01);
functionMap.put(CommonConstant.INT_2, FunctionTest::test02);
}
private static String test01(StringBuilder stringBuilder){
return stringBuilder.append("执行了test01方法").toString();
}
private static String test02(StringBuilder stringBuilder){
return stringBuilder.append("执行了test02方法").toString();
}
public static void main(String[] args) {
// 执行CommonConstant.INT_1策略,程序执行test01方法,并返回一个结果
System.out.println(functionMap.get(CommonConstant.INT_1).apply(new StringBuilder()));
}
}
输出结果:
执行了test01方法
BiFunction<T, U, R>策略应用
/**
* @author ShangHai
* @desc
*/
public class FunctionTest {
private static Map<Integer, BiFunction<User, String, Boolean>> biFunctionMap = new HashMap<>();
static {
biFunctionMap.put(CommonConstant.INT_1, ((user, s) -> user.getUsername().startsWith(s)));
biFunctionMap.put(CommonConstant.INT_2, ((user, s) -> user.getUsername().contains(s)));
}
public static void main(String[] args) {
// 执行CommonConstant.INT_2策略,返回true
System.out.println(biFunctionMap.get(CommonConstant.INT_2).apply(new User("shangHai"), "Hai"));;
}
}
Predicate<T>策略应用
/**
* @author ShangHai
* @desc
*/
public class FunctionTest {
private static Map<Integer, Predicate<String>> predicateMap = new HashMap<>();
static {
predicateMap.put(CommonConstant.INT_1, Predicate.isEqual("aaaa"));
predicateMap.put(CommonConstant.INT_2, str -> str.startsWith("bbbb"));
}
public static void main(String[] args) {
// 执行CommonConstant.INT_1策略,返回true
System.out.println(predicateMap.get(CommonConstant.INT_1).test("aaaa"));
// 执行CommonConstant.INT_2策略,返回false
System.out.println(predicateMap.get(CommonConstant.INT_2).test("aaaa"));
}
}