整点发放优惠券怎么做?必须用到这个谷歌Map神器
上个月的双十一,这月的双十二,打折不断,优惠不停。电商系统中发放优惠券,是一个比较常见的功能。今天讲一个优惠券开发实战。
🍊需求
现在有一个需求,实现不同时间段发放不同优惠券,比如11.11日凌晨0~12点之间发放7折优惠券,12~18点之间发放8折优惠券,18~24点之间发放9折优惠券。
作为开发老油条,你会选用什么数据结构发放优惠券呢?
🍎功能分析
首选明确,这个需求里面有个区间概念,整理如下:
开始时间(含) | 结束时间(不含) | 优惠券 |
---|---|---|
0 | 12 | 7折 |
12 | 18 | 8折 |
18 | 24 | 9折 |
数学表达:
[0, 12) ==> 7折
[12, 18) ==> 8折
[18, 12) ==> 9折
🍒数据结构选择
使用TreeMap
/**
* the RangeTest
* @author Java实用技术手册
* @date 2022-12-17
*/
public class RangeTest {
private static Map<Integer, String> discountMap = new TreeMap<>();
public static void main(String[] args) {
initDiscountMap();
System.out.println("getDiscount_11=" + getDiscount(11));
System.out.println("getDiscount_12=" + getDiscount(12));
}
public static void initDiscountMap() {
discountMap.put(0, Discount.DISCOUNT_7);
discountMap.put(12, Discount.DISCOUNT_8);
discountMap.put(18, Discount.DISCOUNT_9);
}
public static Discount getDiscount(Integer time) {
Objects.requireNonNull(time);
if (time >= 0 && time < 12) {
return discountMap.get(0);
} else if (time >= 12 && time < 18) {
return discountMap.get(12);
} else if (time >= 18 && time < 24) {
return discountMap.get(18);
}
return null;
}
}
大致思路就是使用TreeMap分段设置,查找的时候,比较当前时间处于哪个区间,然后返回对应的value。
上面的代码包括initDiscountMap
和getDiscount
方法,可以看出如果要新增一个时间区间的优惠券,需同时修改这2个方法,违反了代码开闭原则。
使用Guava的TreeRangeMap
之前我们说谷歌神器Guava工具类的时候,提到过多种骚气的Map,其中TreeRangeMap就是一个为区间Map。
当前POM依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
TreeRangeMap描述的是“不相交且非空的区间”到特定值的映射。
内部存储完美符合上面的数学表达式。
[0, 12) ==> 7折
[12, 18) ==> 8折
[18, 12) ==> 9折
使用方法: 先使用TreeRangeMap.create()
创建RangeMap,然后put数据。
key=Range(),value=折扣值。
其中:Range有多个方法,注意根据需求使用。
方法 | 左边 | 右边 | 数学表达 |
---|---|---|---|
open | 开 | 开 | (a, b) |
closed | 闭 | 闭 | [a, b] |
closedOpen | 闭 | 开 | [a, b) |
openClosed | 开 | 闭 | (a, b] |
/**
* the RangeTest
* @author Java实用技术手册
* @date 2022-12-17
*/
public class RangeTest {
private static RangeMap<Integer, Discount> rangeMap = TreeRangeMap.create();
public static void main(String[] args) {
initDiscountMapGuava();
System.out.println("getDiscountGuava_11=" + getDiscountGuava(11));
System.out.println("getDiscountGuava_12=" + getDiscountGuava(12));
}
/**
* 初始化RangeMap,注意key的区间开闭性。
*/
public static void initDiscountMapGuava() {
rangeMap.put(Range.closedOpen(0, 12), Discount.DISCOUNT_7);
rangeMap.put(Range.closedOpen(12, 18), Discount.DISCOUNT_8);
rangeMap.put(Range.closedOpen(18, 24), Discount.DISCOUNT_9);
}
public static Discount getDiscountGuava(Integer time) {
return rangeMap.get(Objects.requireNonNull(time));
}
}
使用RangeMap后,新增一个时间区间优惠券,只要在初始化方法中增加一行数据,而且key的Range设计也比较符合人文理解。
对RangeMap的遍历,可以使用 Map<Range<K>, V> TreeRangeMap#asMapOfRanges()
方法。
以上就是本期内容,希望对你有帮助。
我是Pandas,专注Java编程实用技术分享,公众号《
Java实用技术手册
》和B站均有视频解说,欢迎来玩。如果你觉得这篇文章有用,别忘了点赞+关注,一起进步!
- 点赞
- 收藏
- 关注作者
评论(0)