随机金额砍价代码,可以参考一下
修改变量 TIMES 有惊喜噢
第一个Java文件:
砍价功能代码及实体类测试代码
package com.component.test.controller;
import com.component.test.javacommon.util.GsonUtil;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* 2 * @Author: dengjunbao
* 3 * @Date: 2019/9/6 17:11
* 4
*/
public class Bargain {
/**
* 1.总金额不超过总共可砍的价格*100 单位是分
* 2.每次砍价都能砍到金额,最低不能低于1分,最大金额不能超过(总共可砍的价)*100
*/
private static final int MINMONEY = 1;
private static final int MAXMONEY = 10 * 100;
/**
* 这里为了避免某一次砍价占用大量资金,设定非最后一次砍价的最大金额,
* 把他设置为砍价金额平均值的N倍
*/
private static final double TIMES = 5.1;
/**
* 砍价合法性校验
* 控制金额过小或者过大
*/
private static boolean isRight(int money, int surplusKnife) {
double avg = money / surplusKnife;
//小于最小金额
if (avg < MINMONEY) {
return false;
} else if (avg > MAXMONEY) {
return false;
}
return true;
}
/**
* 随机分配一个金额
*
* @param money:砍价金额
* @param minS:最小金额
* @param maxS:最大金额
* @param surplusKnife
* @return
*/
private static int randomReducePrice(int money, int minS, int maxS, int surplusKnife) {
//若只剩一次,则直接返回
if (surplusKnife == 1) {
return money;
}
//如果最大金额和最小金额相等,直接返回金额
if (minS == maxS) {
return minS;
}
int max = maxS > money ? money : maxS;
//分配砍价正确情况,允许砍价的最大值
int maxY = money - (surplusKnife - 1) * minS;
//分配砍价正确情况,允许砍价最小值
int minY = money - (surplusKnife - 1) * maxS;
//随机产生砍价的最小值
int min = minS > minY ? minS : minY;
//随机产生砍价的最大值
max = max > maxY ? maxY : max;
//随机产生一个砍价
return (int) Math.rint(Math.random() * (max - min) + min);
}
/**
* 砍价----返回一个随机金额
*
* @param money 待砍总价
* @param surplusKnife 待砍刀数
* @return
*/
private static int splitReducePrice(int money, int surplusKnife) {
//金额合法性分析
if (!isRight(money, surplusKnife)) {
return 0;
}
//每次砍价的最大的金额为平均金额的TIMES倍
int max = (int) (money * TIMES / surplusKnife);
max = max > MAXMONEY ? MAXMONEY : max;
int one = randomReducePrice(money, MINMONEY, max, surplusKnife);
return one;
}
/**
获取区间内的一个随机整数
原理:要得到的随机数的范围是[110,130],返回的伪随机数的范围是[0,130),
也即[0,130-1];对得到的这个数模长度是129,于是得到的数的范围是[0,129];
将得到的随机数取余,控制最大值为区间的差数[max-min],这样就可以得到一个区间差数内的一个随机数[min-min,max-min],
再把这个随机数加上最小值,就可以得出[min,max]区间内的一个随机数
*/
private static int getRandom(int min, int max){
Random random = new Random();
int r = random.nextInt(max) % (max - min + 1) + min;
return r;
}
/**
* 该方法用于用户砍价开始时初始化砍价配置
* @param needMoney 待砍总价
* @param minKnife 最少需要砍价刀数
* @param maxKnife 最多需要砍价刀数
* */
private static String getBargainConfig(int needMoney, int minKnife, int maxKnife, HdUser hdUser) {
try {
//获取随机总刀数
int knifeNum = getRandom(minKnife,maxKnife);
System.out.println("随机刀数:"+knifeNum);
Map<String, String> bargainRecordMap = new HashMap<String, String>();
bargainRecordMap.put("needMoney",needMoney + "");
bargainRecordMap.put("knifeNum",knifeNum + "");
bargainRecordMap.put("surplusMoney",needMoney + "");
bargainRecordMap.put("surplusKnife",knifeNum + "");
hdUser.setRemark(GsonUtil.toJson(bargainRecordMap));
}catch (Exception e){
return "102";
}
return "00";
}
/**
* 预砍价----获取一个随机金额
* @param surplusMoney 当前待砍金额
* @param surplusKnife 当前待砍刀数
* */
private static int bargain(int surplusMoney, int surplusKnife) {
//预算这次砍掉的钱
int bargainMoney = 0;
try {
bargainMoney = splitReducePrice(surplusMoney, surplusKnife);
if (surplusMoney < bargainMoney){
bargainMoney = surplusMoney;
}
return bargainMoney;
}catch (Exception e){
e.printStackTrace();
return -1;
}
}
public static void main(String[] args) {
int needMoney = 3800;
int minKnife = 30;
int maxKnife = 60;
HdUser hdUser = new HdUser("xiaoming","");
String sul = getBargainConfig(needMoney, minKnife, maxKnife, hdUser);
if (!"00".equals(sul)){
System.out.println("系统异常");
}
String remark = hdUser.getRemark();
Map<String, String> remarkMap = GsonUtil.fromJson(remark, Map.class);
int knifeNum = Integer.parseInt(remarkMap.get("knifeNum"));
int surplusMoney = Integer.parseInt(remarkMap.get("surplusMoney"));
int surplusKnife = Integer.parseInt(remarkMap.get("surplusKnife"));
int count1 = 0;
int count2 = 0;
for (int i = 0;i < knifeNum;i++){
int res = bargain(surplusMoney,surplusKnife);
if(0 > res){
System.out.println("系统异常");
}
surplusMoney -= res;
surplusKnife --;
count1 += res;
count2 ++;
System.out.println("砍掉"+(double)res/100+"元"+"剩余"+(double)surplusMoney/100+"元"+"剩余"+(double)surplusKnife+"刀");
remarkMap.put("surplusMoney",surplusMoney + "");
remarkMap.put("surplusKnife",surplusKnife + "");
hdUser.setRemark(GsonUtil.toJson(remarkMap));
}
System.out.println("总共砍了"+(double)count1/100+"元-----"+"总共砍了"+count2+"刀");
}
}
class HdUser{
String name = null;
String remark = null;
public HdUser(String name,String remark){
this.name = name;
this.remark = remark;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
第二个java文件:
以下为工具类代码,需要导入google的包
package com.component.test.javacommon.util;
import com.google.gson.*;
import com.google.gson.annotations.SerializedName;
import com.google.gson.annotations.Since;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
public class GsonUtil {
protected final static Log log = LogFactory.getLog(GsonUtil.class);
/** 空的数据 "{}"。 */
public static final String EMPTY_JSON = "{}";
/** 空的数组(集合)数据 - {"[]"}。 */
public static final String EMPTY_JSON_ARRAY = "[]";
/** 默认的日期/时间字段的格式化模式。 */
public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";
public GsonUtil(){
super();
}
/**
* 将target对象转换为json格式字符串
* @param target 要转换的对象
* @param targetType 对象的类型
* @param isSerializeNulls 是否转换空对象(如 : String a = null; isSerializeNulls==true 则转换为 {a:null} ,否则转换为{})
* @param version 配合@Since(Double)注解使用
* (如:@Since(2.0) String a = "x";@Since(1.0) String b = "y";version==null 则注解不生效;
* 如version!=null,则只有@Since<=version的字段才会被转换,如version>=2.0,则转换为{a:"x",b:"y"},version=1.0,则转换为{b:"y"})
* @param datePattern 设置Date时间格式转换为json数据的格式,默认"yyyy-MM-dd HH:mm:ss";
* @param excludesFieldsWithoutExpose 是否只转换@Expose注解的字段,默认false;(如果excludesFieldsWithoutExpose=true,则只有带@Expose注解的字段才会被转换)
* @param adaptTimestamp 使用Timestamp时间适配器转换Timestamp格式为json字符串
* @return
*/
public static String toJson(Object target, Type targetType, boolean isSerializeNulls, Double version,
String datePattern, boolean excludesFieldsWithoutExpose,boolean adaptTimestamp) {
if (target == null) return EMPTY_JSON;
GsonBuilder builder = new GsonBuilder();
if (isSerializeNulls) builder.serializeNulls();
if (version != null) builder.setVersion(version.doubleValue());
if (!StringUtils.hasText(datePattern)) datePattern = DEFAULT_DATE_PATTERN;
if(adaptTimestamp){
TimestampTypeAdapter tt=new TimestampTypeAdapter(datePattern);
builder.registerTypeAdapter(Timestamp.class, tt);
}else builder.setDateFormat(datePattern);
if (excludesFieldsWithoutExpose) builder.excludeFieldsWithoutExposeAnnotation();
return toJson(target, targetType, builder);
}
/**
* 将target对象转换为json格式字符串
* @param target 要转换的对象
* @return
*/
public static String toJson(Object target) {
return toJson(target, null, false, null, null, false, true);
}
/**
* 将target对象转换为json格式字符串(包括空值字段)
* @param target 要转换的对象
* @return
*/
public static String toJsonWithNull(Object target) {
return toJson(target, null, true, null, null, false, true);
}
/**
* 将target对象转换为json格式字符串
* @param target 要转换的对象
* @param datePattern 设置Date时间格式转换为json数据的格式,默认"yyyy-MM-dd HH:mm:ss";
* @return
*/
public static String toJson(Object target, String datePattern) {
return toJson(target, null, false, null, datePattern, false, true);
}
/**
* 将target对象转换为json格式字符串
* @param target 要转换的对象
* @param datePattern 设置Date时间格式转换为json数据的格式,默认"yyyy-MM-dd HH:mm:ss";
* @param adaptTimestamp 使用Timestamp时间适配器转换Timestamp格式为json字符串
* @return
*/
public static String toJson(Object target, String datePattern,boolean adaptTimestamp) {
return toJson(target, null, false, null, datePattern, false, adaptTimestamp);
}
/**
* 将target对象转换为json格式字符串
* @param target 要转换的对象
* @param version 配合@Since(Double)注解使用
* (如:@Since(2.0) String a = "x";@Since(1.0) String b = "y";version==null 则注解不生效;
* @return
*/
public static String toJson(Object target, Double version) {
return toJson(target, null, false, version, null, false, true);
}
/**
* 将target对象转换为json格式字符串
* @param target 要转换的对象
* @param excludesFieldsWithoutExpose 是否只转换@Expose注解的字段,默认false;(如果excludesFieldsWithoutExpose=true,则只有带@Expose注解的字段才会被转换)
* @return
*/
public static String toJson(Object target, boolean excludesFieldsWithoutExpose) {
return toJson(target, null, false, null, null, excludesFieldsWithoutExpose, true);
}
/**
* 将target对象转换为json格式字符串
* @param target 要转换的对象
* @param version 配合@Since(Double)注解使用
* (如:@Since(2.0) String a = "x";@Since(1.0) String b = "y";version==null 则注解不生效;
* @param excludesFieldsWithoutExpose 是否只转换@Expose注解的字段,默认false;(如果excludesFieldsWithoutExpose=true,则只有带@Expose注解的字段才会被转换)
* @return
*/
public static String toJson(Object target, Double version, boolean excludesFieldsWithoutExpose) {
return toJson(target, null, false, version, null, excludesFieldsWithoutExpose, true);
}
/**
* 将target对象转换为json格式字符串
* @param target 要转换的对象
* @param targetType 对象的类型
* @return
*/
public static String toJson(Object target, Type targetType) {
return toJson(target, targetType, false, null, null, false, true);
}
/**
* 将target对象转换为json格式字符串
* @param target 要转换的对象
* @param targetType 对象的类型
* @param version 配合@Since(Double)注解使用
* (如:@Since(2.0) String a = "x";@Since(1.0) String b = "y";version==null 则注解不生效;
* @return
*/
public static String toJson(Object target, Type targetType, Double version) {
return toJson(target, targetType, false, version, null, false, true);
}
/**
* 将target对象转换为json格式字符串
* @param target 要转换的对象
* @param targetType 对象的类型
* @param excludesFieldsWithoutExpose 是否只转换@Expose注解的字段,默认false;(如果excludesFieldsWithoutExpose=true,则只有带@Expose注解的字段才会被转换)
* @return
*/
public static String toJson(Object target, Type targetType, boolean excludesFieldsWithoutExpose) {
return toJson(target, targetType, false, null, null, excludesFieldsWithoutExpose, true);
}
/**
* 将target对象转换为json格式字符串
* @param target 要转换的对象
* @param targetType 对象的类型
* @param version 配合@Since(Double)注解使用
* (如:@Since(2.0) String a = "x";@Since(1.0) String b = "y";version==null 则注解不生效;
* @param excludesFieldsWithoutExpose 是否只转换@Expose注解的字段,默认false;(如果excludesFieldsWithoutExpose=true,则只有带@Expose注解的字段才会被转换)
* @return
*/
public static String toJson(Object target, Type targetType, Double version, boolean excludesFieldsWithoutExpose) {
return toJson(target, targetType, false, version, null, excludesFieldsWithoutExpose, true);
}
/**
* 将json字符串转换为<T>对象
* @param json json格式字符串
* @param token T类型封装器
* @param datePattern 设置json数据的格式转换为Date时间格式,默认"yyyy-MM-dd HH:mm:ss";
* @return
*/
public static <T> T fromJson(String json, TypeToken<T> token, String datePattern) {
if (!StringUtils.hasText(json)) {
return null;
}
GsonBuilder builder = new GsonBuilder();
if (!StringUtils.hasText(datePattern)) {
datePattern = DEFAULT_DATE_PATTERN;
}
Gson gson = builder.create();
try {
return (T)gson.fromJson(json, token.getType());
} catch (Exception ex) {
log.error(json + " 无法转换为 " + token.getRawType().getName() + " 对象!", ex);
return null;
}
}
/**
* 将json字符串转换为<T>对象
* @param json json格式字符串
* @param token T类型封装器
* @return
*/
public static <T> T fromJson(String json, TypeToken<T> token) {
return fromJson(json, token, null);
}
/**
* 将json字符串转换为<T>对象
* @param json json格式字符串
* @param type T类型封装器
* @return
*/
public static <T> T fromJson(String json, Type type) {
Gson gson = new Gson();
return (T)gson.fromJson(json, (Type) type);
}
/**
* 将json字符串转换为clazz类型对象
* @param json json格式字符串
* @param clazz 转换后的目标类型
* @param datePattern 设置json数据的格式转换为Date时间格式,默认"yyyy-MM-dd HH:mm:ss";
* @return
*/
public static <T> T fromJson(String json, Class<T> clazz, String datePattern) {
if (!StringUtils.hasText(json)) {
return null;
}
GsonBuilder builder = new GsonBuilder();
if (!StringUtils.hasText(datePattern)) {
datePattern = DEFAULT_DATE_PATTERN;
}
Gson gson = builder.create();
try {
return gson.fromJson(json, clazz);
} catch (Exception ex) {
log.error(json + " 无法转换为 " + clazz.getName() + " 对象!", ex);
return null;
}
}
/**
* 将json字符串转换为clazz类型对象
* @param json json格式字符串
* @param clazz 转换后的目标类型
* @return
*/
public static <T> T fromJson(String json, Class<T> clazz) {
return fromJson(json, clazz, null);
}
/**
* 将target对象转换为json格式字符串
* @param target 要转换的对象
* @param targetType 对象的类型
* @param builder Gson实例构造器
* @return
*/
public static String toJson(Object target, Type targetType, GsonBuilder builder) {
if (target == null) return EMPTY_JSON;
Gson gson = null;
if (builder == null) {
gson = new Gson();
} else {
gson = builder.create();
}
String result = EMPTY_JSON;
try {
if (targetType == null) {
result = gson.toJson(target);
} else {
result = gson.toJson(target, targetType);
}
} catch (Exception ex) {
log.warn("目标对象 " + target.getClass().getName() + " 转换 JSON 字符串时,发生异常!", ex);
if (target instanceof Collection<?> || target instanceof Iterator<?> || target instanceof Enumeration<?>
|| target.getClass().isArray()) {
result = EMPTY_JSON_ARRAY;
}
}
return result;
}
public static void main(String[] args) {
Properties tp = new Properties();
tp.put("a", "aa");
tp.put("b", "bb");
String json = GsonUtil.toJson(tp.entrySet());
System.out.println(json);
}
}
class SomeObject {
@SerializedName("custom_naming")
private final String someField;
@Since(1.0)
private final String someOtherField;
@Since(2.0)
private final int intFiled;
public SomeObject(String a, String b, int c) {
this.someField = a;
this.someOtherField = b;
this.intFiled = c;
}
}
/**
* timestamp时间类型适配器
* @author lizhiwei
*
*/
class TimestampTypeAdapter implements JsonSerializer<Timestamp>, JsonDeserializer<Timestamp>{
private DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public TimestampTypeAdapter(String pattern){
format=new SimpleDateFormat(pattern);
}
public TimestampTypeAdapter(){}
@Override
public JsonElement serialize(Timestamp src, Type arg1, JsonSerializationContext arg2) {
if(src==null)return null;
String dateFormatAsString = format.format(new Date(src.getTime()));
return new JsonPrimitive(dateFormatAsString);
}
@Override
public Timestamp deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if(json==null)return null;
if (!(json instanceof JsonPrimitive)) {
throw new JsonParseException("数据有误!");
}
try {
Date date = format.parse(json.getAsString());
return new Timestamp(date.getTime());
} catch (java.text.ParseException e) {
// TODO Auto-generated catch block
GsonUtil.log.error(e.getMessage(), e);
return null;
}
}
}