整点发放优惠券怎么做?必须用到这个谷歌Map神器

举报
Java实用技术@Pandas 发表于 2023/03/31 21:37:58 2023/03/31
【摘要】 上个月的双十一,这月的双十二,打折不断,优惠不停。电商系统中发放优惠券,是一个比较常见的功能。今天讲一个优惠券开发实战。

上个月的双十一,这月的双十二,打折不断,优惠不停。电商系统中发放优惠券,是一个比较常见的功能。今天讲一个优惠券开发实战。

image.png

🍊需求

现在有一个需求,实现不同时间段发放不同优惠券,比如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。

上面的代码包括initDiscountMapgetDiscount方法,可以看出如果要新增一个时间区间的优惠券,需同时修改这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站均有视频解说,欢迎来玩。

如果你觉得这篇文章有用,别忘了点赞+关注,一起进步!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。