电商积分券 生成

        最近在做一个电商的项目,其中的一个业务是生成积分券,相信大家都知道,积分券是又一系列的不同的字母和数字组成。这个看起来也不是很难,生成不重复的随机数啦。细想一下视乎还少了一些逻辑,既不能与生成中的重复,也不能和数据库中已有的重复。好了,不啰嗦了,下面咱们看具体实现。


理清逻辑

  • 将已有的进行查找
  • 生成之前和现有的对比
  •  进行保存

当然了生成随机数有多种方式,这里我就使用一种简单的HashSet方法。

 

import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 * 单例工具类,用于生成积分券(由数字和字母组成)
 * @author hanyankun
 * 
 *
 */
public class GenerateRandomNumber {

	private GenerateRandomNumber() {

	}

	private volatile static GenerateRandomNumber instanceGenerateRandomNumber = null;

	private static Lock lock = new ReentrantLock();

	/**
	 * 单例模式 ,doubleCheck
	 * 
	 * @return GenerateRandomNumber
	 */
	public static GenerateRandomNumber getInstance() {

		if (null == instanceGenerateRandomNumber) {

			lock.lock();
			if (null == instanceGenerateRandomNumber) {

				instanceGenerateRandomNumber = new GenerateRandomNumber();
			}

			lock.unlock();

		}
		return instanceGenerateRandomNumber;
	}

	/**
	 * 生成随机数字和字母组合
	 * 
	 * @param length
	 *            字符的长度
	 * @param numSize
	 *            总的个数
	 * @param merchantIntegre  用于存储积分券集合
	 */
	public void getCharAndNumr(int length, int numSize,
			HashSet<String> merchantIntegre) {

		//第一层循环用于生成积分券个数,第二层用于组合积分码
		for (int j = 0; j < numSize; j++) {

			String val = new String("");
			Random random = new Random();
			
			//积分码生成
			for (int i = 0; i < length; i++) {
				// 输出字母还是数字
				String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
				// 字符串
				if ("char".equalsIgnoreCase(charOrNum)) {
					// 取得大写字母还是小写字母
					int choice = random.nextInt(2) % 2 == 0 ? 65 : 97;
					val += (char) (choice + random.nextInt(26));
				} else if ("num".equalsIgnoreCase(charOrNum)) { // 数字
					val += String.valueOf(random.nextInt(10));
				}
			}
			merchantIntegre.add(val);
		}

		// 首次循环完成,可能有重复值,生成的字符串总数小于原有,递归循环再次生成。
		while (merchantIntegre.size() < numSize) {
			numSize = numSize - merchantIntegre.size();
			// 继续循环生成
			getCharAndNumr(length, numSize, merchantIntegre);

		}

	}

}


说明:

以上为创建的单例工具类,使用双重Lock锁方法防止多实例。getCharAndNumr方法为积分券生成方法。

 

单元测试

 

 我们模拟一种数据库已经有部分数据,再次生成一部分数据

public class GenerateRandomNumberTest {

	HashSet<String> merchantSet = new HashSet<String>(); // 仿真数据库数据
	int length = 10;    //生成的积分券长度
	int numSize = 1024;  //数据库中已有1024条数据

	@Before
	public void setUp() throws Exception {

		GenerateRandomNumber.getInstance().getCharAndNumr(length, numSize,
				merchantSet);

		System.out.println("数据库原有积分券个数是:"+merchantSet.size() +" ");
	}

	@Test
	public void testGetCharAndNumrIntIntHashSetOfString() {
		HashSet<String> merchantSet2 = new HashSet<String>(); // 仿真数据库数据
		merchantSet2.addAll(merchantSet) ; //临时存储数据库查询到的数据(浅拷贝)
		
		//再次生成1万个积分券,但是总个数却是11024个
		GenerateRandomNumber.getInstance().getCharAndNumr(10, 10000,
				merchantSet);
		
		
		System.out.println("生成的积分券总个数是: "+merchantSet.size());
		
		//因为传入时已经带有部分数据, 需要删除原有数据
		
		merchantSet.removeAll(merchantSet2);  //删除数据库中原有数据, 保留新增数据
		
		System.out.println("新增积分券个数是: "+merchantSet.size());
		


	}

}


打印数据为:

 


总结:

 

总体来说,用于的还是最基本的java基础,随机数,单例模式以及集合的操作,包括深拷贝与浅拷贝。基本功还是的要牢固呀。



评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值