SpringBoot实现抽奖算法的示例代码

 更新时间:2023年06月12日 14:05:14   作者:越走越远的风  
这篇文章主要为大家详细介绍了如何通过SpringBoot实现抽奖算法,文中的示例代码简洁易懂,具有一定的参考价值,感兴趣的小伙伴可以了解一下

前言

当我们参加各种活动和抽奖时,抽奖环节总是能引起极大兴趣和关注。抽奖的公正性和随机性是保证活动公平和成功的重要因素。

本文将介绍抽奖算法的实现原理及其在Java编程语言中的应用,以帮助读者了解抽奖程序的实现细节,同时也为读者提供一些有用的参考和借鉴。

创建抽奖表

CREATE TABLE `app_draw_prize` (
  `id` bigint NOT NULL,
  `activity_id` int unsigned DEFAULT NULL COMMENT '活动id',
  `name` varchar(50) DEFAULT NULL COMMENT '奖品名称',
  `url` varchar(200) DEFAULT NULL COMMENT '图片地址(未使用)',
  `value` varchar(10) DEFAULT '0' COMMENT '值',
  `probability` double unsigned DEFAULT '0' COMMENT '概率',
  `type` tinyint unsigned DEFAULT NULL COMMENT '类型',
  `status` tinyint unsigned DEFAULT '0' COMMENT '上下架状态:0下架1上架',
  `position` tinyint(1) DEFAULT NULL COMMENT '位置',
  `day_max_times` tinyint unsigned DEFAULT '0' COMMENT '每天最多中奖次数,大于0时生效',
  `month_max_times` tinyint unsigned DEFAULT '0' COMMENT '每月最多中奖次数,大于0时生效',
  `show` tinyint unsigned DEFAULT '0' COMMENT '是否首页展示中奖记录0否1是',
  `default_prize` tinyint(1) DEFAULT '0' COMMENT '抽奖上限时直接返回默认奖品',
  `ref_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '关联id',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='抽奖奖品表';

抽奖代码

算法思路

1.将奖品按集合中顺序概率计算成所占比例区间,放入比例集合。并产生一个随机数加入其中,排序。

2.排序后,随机数落在哪个区间,就表示那个区间的奖品被抽中。

3.返回的随机数在集合中的索引,该索引就是奖品集合中的索引。

4.比例区间的计算通过概率相加获得。

private DrawPrize doDrawPrize(Long activityId, Long userId) {  
    List<DrawPrize> drawPrizes = drawPrizeMapper.selectList(new LambdaQueryWrapper<DrawPrize>()  
            .eq(DrawPrize::getActivityId, activityId)
            .eq(DrawPrize::getStatus, 1)
            .orderByDesc(DrawPrize::getProbability));  
    List<Double> probLists = new ArrayList<>(drawPrizes.size());  
    Double sumProb = 0D;  
    for (DrawPrize drawPrize : drawPrizes) {  
        sumProb += drawPrize.getProbability();  
    }  
    if (sumProb <= 0) {  
        throw new IllegalArgumentException("抽奖概率设置错误");  
    }  
    Double rate = 0D;  
    for (DrawPrize drawPrize : drawPrizes) {  
        rate += drawPrize.getProbability();  
        probLists.add(rate / sumProb);  
    }  
    double random = Math.random();  
    probLists.add(random);  
    Collections.sort(probLists);  
    DrawPrize drawPrize = drawPrizes.get(probLists.indexOf(random));  
    if (drawPrize.getDayMaxTimes() > 0) {  
        //判断当天中奖次数  
        String daily = DateUtil.formatDate(new Date());  
        Long count = drawRecordMapper.selectCount(new LambdaQueryWrapper<DrawRecord>()  
                .eq(DrawRecord::getMemberId, userId)  
                .eq(DrawRecord::getPrizeId, drawPrize.getId())  
                .eq(DrawRecord::getDaily, daily));  
        if (count >= drawPrize.getDayMaxTimes()) {  
        //直接返回谢谢参与  
            return drawPrizes.stream()  
                    .filter(d -> d.getDefaultPrize() == 1)  
                    .findFirst()  
                    .orElseThrow(() -> new IllegalArgumentException("抽奖错误"));  
        }  
    }  
    if (drawPrize.getMonthMaxTimes() > 0) {  
        //判断当月中奖次数  
        Long count = drawRecordMapper.selectCount(new LambdaQueryWrapper<DrawRecord>()  
                .eq(DrawRecord::getMemberId, userId)  
                .eq(DrawRecord::getPrizeId, drawPrize.getId())  
                .eq(DrawRecord::getMonth, DateUtil.month(new Date())));  
        if (count >= drawPrize.getMonthMaxTimes()) {  
        //直接返回谢谢参与  
            return drawPrizes.stream()  
                    .filter(d -> d.getDefaultPrize() == 1)  
                    .findFirst()  
                    .orElseThrow(() -> new IllegalArgumentException("抽奖错误"));  
        }  
    }  
    return drawPrize;  
}

到此这篇关于SpringBoot实现抽奖算法的示例代码的文章就介绍到这了,更多相关SpringBoot抽奖算法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot注解梳理(小结)

    SpringBoot注解梳理(小结)

    这篇文章主要介绍了SpringBoot注解梳理(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • SpringSecurity构建基于JWT的登录认证实现

    SpringSecurity构建基于JWT的登录认证实现

    这篇文章主要介绍了SpringSecurity构建基于JWT的登录认证实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • mybatisPlus更新字段值为null的解决方案

    mybatisPlus更新字段值为null的解决方案

    在使用mybatis-plus时,发现当前端传入的值为null值时,结果无论怎么操作后端都不执行更新null字段的操作,下面这篇文章主要给大家介绍了关于mybatisPlus更新字段值为null的解决方案,需要的朋友可以参考下
    2023-04-04
  • 因不会远程debug调试我被项目经理嘲笑了

    因不会远程debug调试我被项目经理嘲笑了

    这篇文章主要介绍了远程debug调试的相关内容,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-08-08
  • Spring Boot 定制与优化内置的Tomcat容器实例详解

    Spring Boot 定制与优化内置的Tomcat容器实例详解

    本文主要记录对内置容器优化和定制的方式,用于自己加深对SpringBoot理解。本文给大家介绍的非常详细,具有参考借鉴价值,需要的朋友参考下吧
    2017-12-12
  • Java 中的类和对象详情

    Java 中的类和对象详情

    这篇文章主要介绍了Java 中的类和对象,类可以看成是创建Java对象的模板,下面文章围绕着Java 类与对象详细内容展开,需要的朋友可以参考一下
    2021-11-11
  • 在Spring 中使用@Aspect 控制自定义注解的操作

    在Spring 中使用@Aspect 控制自定义注解的操作

    这篇文章主要介绍了在Spring 中使用@Aspect 控制自定义注解的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • 快速掌握Java8中的Optional

    快速掌握Java8中的Optional

    Optional 是一个容器类,代表一个值存在或不存在,Optional并不是用来替换所有的null,而是为了在设计良好的API中更明确地表达可能缺失的值,这篇文章主要介绍了Java8的Optional及使用,需要的朋友可以参考下
    2023-07-07
  • Java如何基于反射机制获取不同的类

    Java如何基于反射机制获取不同的类

    这篇文章主要介绍了Java如何基于反射机制获取不同的类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • Eclipse配置Tomcat和JDK步骤图解

    Eclipse配置Tomcat和JDK步骤图解

    这篇文章主要内容是Eclipse配置Tomcat和JDK步骤图解,需要的朋友可以参考下
    2015-08-08

最新评论