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.發紅包不僅有普通紅包,還有手氣紅包,那麼可以用到隨機數的知識來解決,博主將在後期慢更之,歡迎各位大犇給出自己的解法。

感謝您的閱讀,不足之處歡迎指正!

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章