JAVA-抢红包小程序设计

JAVA

第三章 抢红包小程序设计1


一、简要要求

编写一个将红包金额按一定数量随机分配的小程序。红包金额最大不能超过 200 元,每个人分到的红包最小不能少于 1 分钱,红包的最小单位是分

二、实现

1.定义工具类RedPacketUtil

类中定义类属性:最小红包额度,最大红包额度,每个红包最大金额是平均值的倍数等;
定义isRight()函数检查红包金额的合法性,如平均值小于最小金额,总金额大于红包金额的最大值等都判断为不合法。
定义List splitRedPackets(int money, int count) 方法:参数分别为红包总金额(单位:分)和红包数量,将分配好的红包放入 List 集合。首先调用检查函数,如果金额不合法,抛出:“红包金额不合法”的自定义异常;根据红包数,红包总金额,红包最大金额和最小金额,循环调用随机产生每个红包值的函数randomVal(),返回值存入list集合。
定义随机产生单个红包值函数randomVal():首先进行判断,如果红包数量为1,直接返回金额;最大金额和最小金额相等,直接返回金额。随机产生一个红包值,(int)Math.rint(Math.random() * (每个红包的最大值 - 每个红包的最小值) + 每个红包的最小值)) % 每个红包的最大值 + 1(单位都是分)。判断是否合法isRight(剩余金额,剩余红包数),合法就返回。否则,如果下一轮红包平均值比最小值小,将此轮产生的红包值作为最大值,递归调用随机生成函数;如果下一轮红包平均值比最大值大,将此轮产生的红包值作为最小值,递归调用随机生成函数。
自定义异常类,继承Exception,简单抛出提示信息即可。

代码如下:

import java.util.List;
import java.util.ArrayList;
public class RedPacketUtil {
	List<Integer> list = new ArrayList();
	public RedPacketUtil() {}
	public RedPacketUtil(double money,int count) {
		this.money=money;
		this.count=count;
	}
	double min=0.01;//最小红包额度
	double maxmoney=200;//最大红包额度
	double money;
	int count;//红包数量
	double minMoney=0.01;
	boolean isRight() {
		boolean a=true;
		if(money/count<min||money>200||money<0.01) {
			a=false;
		}
		return a;
	}
	public List<Integer> splitRedPackets(int money, int count) throws MyException{
		this.money=money;
		this.count=count;
	    boolean b=isRight();
	    if(b==false) { throw new MyException("红包金额不合法");}
		for (int i = 1; i <=count; i++) {//生成count个100内的随机数
	    double r=randomVal();
		list.add((int) r);//存入list集合
		}
		for(int i=0;i<list.size();i++) {
			System.out.printf(list.get(i)+"  ");
		}System.out.print("\n");return list;
		}
	public double randomVal() {
		if(count==1||money==min) {return money;}
		double max=2*money/count;
		double x=Math.random();
		//System.out.print(x+" ");
		double m=Math.rint((x*(max-min)+min)%max+1);
		//System.out.println(m);
		money=money-m;
		count--;
		if(isRight()==false) {
			
			if(money/count<min) {
				min=m;
				randomVal();
			}
			if(money/count>max) {
				min=m;
				randomVal();
			}
			//红包数额分配
		}
		return m;
	}
}

2.自定义异常类,继承Exception,简单抛出提示信息

代码如下:

public class MyException extends Exception{
	public MyException() {}
	public MyException(String s) {
		System.out.println(s);
	}
}

3.编写模拟人员抢红包,并展示红包领取详情

定义RedEnvelope 类,可能用到的属性: 红包金额(分),红包数目 ,发送日期,第一个人抢红包的开始时间,红包抢完后的结束时间,List bag; // 分配到的红包列表(分),Map<String,Double> info; // 红包领取信息。
定义一个 open 的方法,该方法携带一个参数 name,表明是这个人打开了红包,在该方法中实现以下功能:如果超过 5 秒没人领取,红包过期,当再打开红包时,输出:“红包已经过期”;如果未过期,且第一个人打开红包时,将 start 设为当前时间,记录下红包开始领取的时间,将红包列表的最后一个值给该人,第二个人打开时就将红包列表的倒数第二位的值给他,输出:“恭喜xx,领取到了xx元”,并将姓名作为 key,红包金额作为 value 存到集合HashMap中(注意:输出和存储是需要将分转换为元,除以 100.0),将红包数量减去一,并判断红包数量是否为零,如果为零则获取当前时间为红包领取完的时间,计算红包几秒领取完毕,输出:“红包被抢完,一共用了xx秒”,后面的人领取红包时依次类推;如果红包领完后,且红包未过期,输出:“xx手速慢了,红包都没啦”;
showInfo():该方法实现打印红包领取详情,输出格式为:“xx抢到了xx元”,当所有红包领取详情输出完毕后,最后输出谁是运气王,输出格式为:“其中,xx是运气王,抢到了xx元”。

代码如下:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.HashMap;
public class RedEnvelope {
	int redmoney;
	int num;
	Date setdate;
	long star;
	long end;
	List<Integer> bag;
	Map<String,Double> info;
	public RedEnvelope() {}
	public void RedEnvelope(int m,int b,List<Integer> bag) {
		this.num=b;
		this.redmoney=m;
		this.bag=bag;{
			info=new HashMap<>();
			setdate=new Date();
		}
	}
	public void open(String name) {
	       int second = (int)((new Date().getTime()- setdate.getTime()) / (1000));
	        if (second < 5){
	            if ( info.size() == 0 ){
	                star= new Date().getTime();
	            }
	            if (num > 0 ){
	                double nowMoney = bag.get(num - 1)/100.0;
	                info.put(name, nowMoney);
	                System.out.println("恭喜" + name + ",抢到了" + nowMoney + "元");
	                num--;
	            }
	            if (num == 0){
	                end = new Date().getTime();
	                System.out.println("红包被抢完,一共用了" + ((int)((end - star) / (1000))) + "秒");
	                num = -1;
	                return;
	            }
	            if(num == -1){
	                System.out.println( name + "手速慢了,红包都没啦");
	            }
	        }
	        else {
	            System.out.println( name + ":红包已经过期");
	        } 
	}
	public void showInfo(){
		double max=0;
        for(Entry<String, Double> entry : info.entrySet()){
            max = entry.getValue() > max ? entry.getValue() : max;
            System.out.printf( "%s抢到了%.2f元\n", entry.getKey(),entry.getValue());
        }
        for(Entry<String, Double> entry : info.entrySet()){
            if (entry.getValue() == max){
                System.out.printf( "其中,%s是运气王,抢到了%.2f元\n", entry.getKey(),entry.getValue());
                break;
            }
            }
	}
}

4.编写一个测试类,生成产生红包类对象

代码如下:

import java.util.List;
import java.util.ArrayList;
import java.util.Scanner;
public class text4 {
	public static void main(String[] args) throws MyException { 
		Scanner in=new Scanner(System.in);
		System.out.println("请输入红包金额:");
		int a=in.nextInt();
		System.out.println("请输入红包个数:");
		int b=in.nextInt();
		RedPacketUtil c=new RedPacketUtil();
		c.splitRedPackets(a,b);
		RedEnvelope d=new RedEnvelope();
		d.RedEnvelope(a,b,c.list);
		System.out.println("请输入抢红包人名:");
		d.open(in.next());
		d.open(in.next());
		d.open(in.next());
		d.open(in.next());
		d.open(in.next());
		d.showInfo();
	}
}

总结

调出来了
在这里插入图片描述
自己输入人名啥的就能抢了

  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
好的,这是一个关于Java线程池的问题,让我来为您解答。 首先,需要导入Java自带的线程池包——java.util.concurrent.ExecutorService。您可以定义一个线程池对象,然后使用execute方法将任务提交到线程池中执行。 以抢红包程序为例,首先定义一个抢红包的方法,该方法需要传入一个最大金额一个最小金额,返回抢到的金额。 然后,在主方法中创建一个线程池对象,并通过for循环提交5个任务,每个任务都是一个Runnable对象。在每个任务中调用抢红包方法,最后输出每个线程最后抢得的红包金额即可。 下面是代码示例,供参考: ``` import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class RedPacketDemo { // 抢红包方法 public static double grabRedPacket(double min, double max) { Random random = new Random(); return random.nextDouble() * (max - min) + min; } public static void main(String[] args) { // 创建一个固定大小的线程池 ExecutorService executor = Executors.newFixedThreadPool(5); // 提交5个任务 for (int i = 0; i < 5; i++) { final int threadNum = i + 1; // 线程编号 executor.execute(new Runnable() { @Override public void run() { double redPacket = grabRedPacket(1, 100); // 抢红包 System.out.println("Thread " + threadNum + " grabbed " + redPacket + " yuan."); } }); } // 关闭线程池 executor.shutdown(); } } ``` 希望这个示例代码对您有所帮助!如果您还有其他问题需要解答,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值