Java实现微信、QQ等群主发红包实例(普通红包)

许久没有写blog

手有点生,但是准备开启常更模式了!

最近重拾Java知识,挑一些有趣的案例分享给大家。


分析:

首先,群主和成员都是微信、QQ等应用程序的用户,他们都可以归为用户类,那么由此我们可以很快地想到Java中一个很重要的特性:继承性。

一张图很直观地表达其关系:

其次,分析本程序的一些逻辑:

假设群主和成员本来都有一些钱(可以为0)

群主发的一笔金额(红包),从群主余额中扣除,平均分成n等份,让成员领取;成员领取红包后,保存到成员各自的余额中。


实现:

首先,定义用户类User

public class User {
    // 成员变量
    private String username; // 用户名
    private double leftMoney; // 余额,有角和分

    // 构造方法
    public User() {
    }

    public User(String username, double leftMoney) {
        this.username = username;
        this.leftMoney = leftMoney;
    }
    
    // get/set方法
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public double getLeftMoney() {
        return leftMoney;
    }

    public void setLeftMoney(double leftMoney) {
        this.leftMoney = leftMoney;
    }

    // 展示信息的方法
    public void show() {
        System.out.println("用户名:"+ username +" , 余额为:" + leftMoney + "元");
    }
}

(小技巧)快速创建Getter/Setter方法:

Alt + Insert

选择:

Getter and Setter

同理,user无参数方法和有参数方法快速创建可以选择:

Constructor

Select All和Select None即可实现全选和全不选。


其次,可以定义群主类Manager

public class Manager extends User {
    // 添加构造方法
    public Manager() {
    }

    public Manager(String username, double leftMoney) {
        // 通过super 调用父类构造方法
        super(username, leftMoney);
    }
    
    public ArrayList<Double> send(double money, int count) {
        // 获取群主余额
        double leftMoney = getLeftMoney();
        // 如果发出去的红包大于群主剩余钱,则发送失败
        if(money > leftMoney) {
            System.out.println("发送失败!");
            return null;
        }

        // 修改群主余额的
        super.setLeftMoney(leftMoney ‐ money);

        // 创建一个集合,保存等份金额
        ArrayList<Double> list = new ArrayList<>();
    
        // 扩大100倍,相当于折算成'分'为单位,避免小数运算损失精度的问题
        money *= 100;
        money = (int)money;
    
        // 每份的金额
        int avg = (int)(money / count);

        // 不能整除的余数
        int mod = (int)(money % count);
    
        // 无论是否整除,n‐1份,都是每份的等额金额
        for (int i = 0; i < count ‐ 1; i++) {
            // 缩小100倍,折算成 '元'
            list.add(avg / 100.0);
        }
    
        // 将最后一份不能整除的金额放到list的最后
        double last = (avg + mod)/100.0;
        list.add(last);
        
        // 返回集合
        return list;
    }
}

其中,要考虑到群主发的红包可能不是整数,且红包数为整数,那么有可能不能平均分配,所以我先平均分配,将多余的不能平均分配的金额放到最后一个红包内。


然后,我们定义成员类Member

public class Member extends User {
    public Member() {
    }
    
    public Member(String username, double leftMoney) {
        super(username, leftMoney);
    }
    
    // 打开红包,就是从集合中,随机取出一份,保存到自己的余额中
    public void receive(ArrayList<Double> list) {
    
    // 创建一个Random对象,随机生成一个红包编号
    int index = new Random().nextInt(list.size());
    
    // 从集合中移去相应编号,得到该编号的金额的红包
    double delta = list.remove(index);

    // 当前成员本来有多少钱
    double money = super.getLeftMoney();
    
    // 直接调用父类方法,设置到余额
    super.setLeftMoney( money + delta );
    }
}

最后,写执行程序,main函数执行:

public class mainRedPacket {
    public static void main(String[] args) {
    // 创建一个群主对象,三个成员
    Manager manager = new manager("群主" , 188.88);
    Member one = new Member("成员A",5.23);
    Member two = new Member("成员B",0);
    Member three = new Member("成员C",16.89);

    // 显示原始成员的余额
    manager.show();
    one.show();
    two.show();
    three.show();
    System.out.println("=================");
    
    // 创建一个键盘录入
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入发送红包的金额:");
    double money = sc.nextDouble();

    // 发送红包
    ArrayList<Double> list = manager.send(money,3);
    
    // 打开红包
    one.receive(list);
    two.receive(list);
    three.receive(list);

    // 显示余额信息
    manager.show();
    one.show();
    two.show();
    three.show();
    }
}

结果展示:

分别进行三次红包发送:

第一次:群主余额188.88元,发送200元红包,发送失败,余额不足!

第二次:群主发送18元红包,三个人正好平分,每人6元。

第三次:群主发送0.31元红包,三人不能平分,所以其中一人多0.01元。

三次结果均正确


思考:

1.对于double类型的精度并没有控制,很又可能出现浮点数相加减或相乘除精度不正确的情况,读者可以自行思考,或者百度解决。

2.发红包不仅有普通红包,还有手气红包,那么可以用到随机数的知识来解决,博主将在后期慢更之,欢迎各位大犇给出自己的解法。

感谢您的阅读,不足之处欢迎指正!

发布了3 篇原创文章 · 获赞 4 · 访问量 2210

猜你喜欢

转载自blog.csdn.net/buluxianfeng/article/details/104705155