注册 登录
编程论坛 JAVA论坛

(详解)新年过好,突发奇想,微信红包。就写了微信红包的代码。不知道是否正确!

tequilashou 发布于 2021-02-20 16:14, 4929 次点击
先上图
只有本站会员才能查看附件,请 登录

只有本站会员才能查看附件,请 登录
只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2021-2-20 16:34编辑过]

11 回复
#2
tequilashou2021-02-20 16:23
首先建一个maven  jar工程

工程中有4个包

cn.hz.contor 下的RunPcket.java 为主函数入口

cn.hz.model 为建模
    Packet.java 为红包类
    Person.java 为人类
两个类都是 javaBean pojo类

cn.hz.packet 为抢红包核心类
    RedPacketInter.java 为接口
    RedPacketImpl.java  为接口实现
cn.utils
    SpringRum.java Spring 获取工具
    TaskExcutorConfig.java 多线程

测试工具 JUnit 5
   
#3
tequilashou2021-02-20 16:24

Person 类

程序代码:
package cn.hz.model;

import org.springframework./**

 * 人员类

 *

 * *
*/

@Component

public class Person {
   
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Person(String name) {
        super();
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + "]";
    }
   
   

}
#4
tequilashou2021-02-20 16:25
package类


程序代码:
package cn.hz.model;

import org.springframework./**

 * 红包类

 *

 *

 * *
*/


@Component
public class Packet {
   
    private double total;//红包金额
   
    private int num;//红包个数
   
    private long time;//抢红包的时间

    public double getTotal() {
        return total;
    }

    public void setTotal(double total) {
        this.total = total;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }

    public Packet() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Packet(double total, int num, int time) {
        super();
        this.total = total;
        this.num = num;
        this.time = time;
    }

    @Override
    public String toString() {
        return "Packet [total=" + total + ", num=" + num + ", time=" + time + "]";
    }

   
   
   
   
   
   

}
#5
tequilashou2021-02-20 16:26
RedPacketInter 接口

程序代码:
package cn.hz.packet;

import cn.hz.model.Packet;
import cn.hz.model.Person;

/**

 * 抢红包逻辑业务处理的接口

 *

 * *
*/
public interface RedPacketInter {
   
   
    //发红包的方法
    public double SetMake(String name, double money,int num);
   
    //抢红包的方法
    public double SubMake(String name);

}
#6
tequilashou2021-02-20 16:27
RedPacketImpl 接口实现核心代码
程序代码:
package cn.hz.packet;



import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Random;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.import cn.hz.model.Packet;
import cn.hz.model.Person;
import cn.utils.SpringRun;

/**

 * 接口实现

 *

 * *
*/



@Component

public class RedPacketImpl implements RedPacketInter{
   
    private int sum=1;//红包记录器,
   
    @Autowired
    private Person per;//成员变量Person类
   
    @Autowired
    private Packet pak;//成员变量Packet类
   
        
   
//发红包的方法
    @Override
    public double SetMake(String name, double money,int num) {
        // TODO Auto-generated method stub
        per.setName(name);//传入发布红包人
        pak.setTotal(money);//传入红包金额
        pak.setNum(num);//传入红包个数
        
        if(pak.getTotal()>0 && pak.getTotal()<=200 && pak.getNum()>=1){//健壮性判断 红包不能小于0 大于200,红包个数不能小于0
            
            pak.setTotal(money);//将发布的红包金额传入红包类,红包金额
            pak.setNum(num);//将发布的红包个数放入红包类
            
            System.out.println(per.getName()+"发布了"+pak.getNum()+"个"+pak.getTotal()+"元的红包");
        }
        else {
            //如果违反了判断的规则就抛出运行时异常,结束程序
            throw new RuntimeException("红包最大200限制。并且金额不能为0,红包个数不能为0");
        }
   
        return pak.getTotal();
    }
   
   
   
    //抢红包的方法
     @Async
    @Override
    public synchronized double SubMake(String name) {
        // TODO Auto-generated method stub
        
         long S_time= System.currentTimeMillis();//这里是设置初始值毫秒
        
        
//因为有判断的方法体,所以这两个变量就要定义在这里,不然会报错
          double total=0;
          Double menoys = pak.getTotal();
         
         
              
        if(pak.getNum()<=0) {//首先判断红包个数,如果没有红包就直接返回-1
            
            System.out.println("你的动作慢了"+sum+"个红包"+pak.getTime()+"毫秒被抢光了");
            
            return -1;
        }
         
         
       if(pak.getNum()==1){//其次判断红包剩余1个的时候红包余额就是最后一个人的
         
           pak.setTotal(pak.getTotal());
           
           System.out.println(name+"抢到了一个红包,金额:"+menoys+"元!剩余红包"+0+"元!");
           
           pak.setNum(pak.getNum()-1);//红包个数减少1个
           
           return 0;
        
        }
      
                     
              per.setName(name);//抢红包者
            
            pak.setNum(pak.getNum()-1);//红包个数减少1个
            
                Random rand=(Random) SpringRun.getSpringContext().getBean("random");//拿到Random类
               
                /*
                 * if(pak.getNum()>0 && pak.getTotal()<=0) {
                 *
                 * System.out.println("触发"); }
                 
*/
                        
                double menoy= rand.nextDouble()*(pak.getTotal()/pak.getNum());//用 Random 类下的方法获取随机数
               
//这里的计算公式是为了保证有红包个数必定就有红包余额。所以随机数是红包金额除以红包个数中随机
               
                DecimalFormat df=new DecimalFormat("0.00");//初始化四舍五入 小数后2位
                 
                String menoyDF=df.format(menoy);//拿到四舍五入后的值
                 
                menoys=Double.parseDouble(menoyDF);//转换成double类型
                 
                 total= pak.getTotal()-menoys;  //红包金额减去抢到的红包获得剩余红包
               
               
//将剩余红包也进行格式化四舍五入
                String totalDF=df.format(total);
               
                pak.setTotal(Double.parseDouble(totalDF));
           
        System.out.println(name+"抢到了一个红包,金额:"+menoys+"元!剩余红包"+pak.getTotal()+"元!");
        
        System.out.println("还剩余"+pak.getNum()+"红包");
        
        
         long E_time= System.currentTimeMillis();//设置结束时间
         
         long time=(E_time-S_time);//抢红包的毫秒数
                        
         pak.setTime(pak.getTime()+time);//累加放入 Packet模型
         
        sum++;//每次记录器+1
         
        return pak.getTotal();
    }




}
#7
tequilashou2021-02-20 16:28
SpringRun Spring 拿取对象工具

程序代码:
package cn.utils;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public  class  SpringRun {
   
    public static ApplicationContext getSpringContext() {
        
        ApplicationContext cont=new ClassPathXmlApplicationContext("bean.xml");
        
        return cont;
        
        
    }

}
#8
tequilashou2021-02-20 16:29
多线程

程序代码:
package cn.utils;

import java.util.concurrent.Executor;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration

@EnableAsync  // 启用异步任务

public class TaskExcutorConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(5);
        taskExecutor.setMaxPoolSize(10);
        taskExecutor.setQueueCapacity(25);
        taskExecutor.initialize();
        return taskExecutor;
    }
}
#9
tequilashou2021-02-20 16:30
JUnit 5 测试


程序代码:

import java.util.Random;

import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.hz.contorl.RunPacket;
import cn.hz.model.Person;
import cn.hz.packet.RedPacketImpl;
import cn.hz.packet.RedPacketInter;
import cn.utils.SpringRun;

class test {

    @Test
    void test() {
        
            
        ApplicationContext cont=SpringRun.getSpringContext();
        
        
        RedPacketInter packet=(RedPacketInter) cont.getBean("redPacketImpl");
        
   
   
        
        packet.SetMake("张三", 10,10);
        packet.SubMake("李四");
        packet.SubMake("王五");
        packet.SubMake("赵六");
        packet.SubMake("钱7");
        packet.SubMake("王五");
        packet.SubMake("赵六");
        packet.SubMake("钱7");
        packet.SubMake("钱7");
        packet.SubMake("李四");
        packet.SubMake("王五");
        packet.SubMake("赵六");
        packet.SubMake("钱7");
        packet.SubMake("王五");
        packet.SubMake("赵六");
        packet.SubMake("钱7");
        packet.SubMake("钱7");
        /*
         * packet.SubMake("钱7"); packet.SubMake("孙8"); packet.SubMake("张小花");
         
*/
        
    }

}
#10
tequilashou2021-02-20 16:31
运行结果

只有本站会员才能查看附件,请 登录

只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2021-2-20 16:32编辑过]

#11
刘腾龙2021-07-02 16:30
大佬,牛呀牛呀
#12
包子还是饼干2021-11-01 17:41
膜拜大佬
1