Java實(shí)現(xiàn)微信發(fā)紅包
前言
紅包文化源遠(yuǎn)流長(zhǎng)。從古時(shí)的紅色紙包,到手機(jī)App中的手氣紅包,紅包作為一種獨(dú)特的中華文化傳承至今。之前的所有內(nèi)容中,綜合Java這方面的知識(shí),可以模擬發(fā)普通紅包。那么這篇博客,我將整合之前介紹的所有的技術(shù)和知識(shí),編寫(xiě)一個(gè)帶界面版的 發(fā)紅包 案例。
需求分析
分析并使用已給出的類(lèi),編寫(xiě)程序,設(shè)置紅包類(lèi)型。
小貼士 紅包類(lèi)型:
1.普通紅包:金額均分。不能整除的,余額添加到最后一份紅包中。
2.手氣紅包:金額隨機(jī)。各個(gè)紅包金額累和與總金額相等。
紅包場(chǎng)景: 此案例是模擬群主給群成員發(fā)紅包,群主自己打開(kāi)最后一個(gè)紅包的場(chǎng)景。
案例實(shí)現(xiàn)
環(huán)境搭建:
1.創(chuàng)建項(xiàng)目:名稱自定義,建議為 RedPacketDemo 。
2.導(dǎo)入圖片:將 pic 目錄,導(dǎo)入項(xiàng)目中,與 src 目錄平級(jí)。
3.導(dǎo)入已知類(lèi):在 src 下創(chuàng)建一個(gè)包,名字自定義,存放編輯的類(lèi)。
1. RedPacketFrame :(界面)
一個(gè)抽象類(lèi),包含了一些屬性,是紅包案例的頁(yè)面。
public abstract class RedPacketFrame extends JFrame {
/* ownerName : 群主名稱 */
public String ownerName = "誰(shuí)誰(shuí)誰(shuí)誰(shuí)";
/* openMode : 紅包的類(lèi)型 [普通紅包/手氣紅包] */
public OpenMode openMode = null;
/**
* 構(gòu)造方法:生成紅包界面.
* @param title 頁(yè)面的標(biāo)題.
*/
public RedPacketFrame(String title) {
super(title);
init();// 頁(yè)面相關(guān)的初始化操作
}
/* set方法 */
public void setOwnerName(String ownerName) {
this.ownerName = ownerName;
}
public void setOpenMode(OpenMode openMode) {
this.openMode = openMode;
}
}
2. OpenMode :(類(lèi)型)
一個(gè)接口,包含一個(gè)分配方法,用來(lái)指定紅包類(lèi)型。
public interface OpenMode {
/**
* @param totalMoney 總金額,單位是"分"。總金額為方便計(jì)算,已經(jīng)轉(zhuǎn)換為整數(shù),單位為分。
* @param count 紅包個(gè)數(shù)
* @return ArrayList<Integer> 元素為各個(gè)紅包的金額值,所有元素的值累和等于總金額.
*
* 請(qǐng)將totalMoney,分成count分,保存到ArrayList<Integer>中,返回即可.
*/
public abstract ArrayList<Integer> divide(int totalMoney, int count);
}
3. 定義 RedPacket:
RedPacket 類(lèi),繼承 RedPacketFrame :
public class RedPacket extends RedPacketFrame {
public RedPacket(String title) {
super(title);
}
}
4. 定義測(cè)試類(lèi),創(chuàng)建 RedPacket:
public class RedPacketTest {
public static void main(String[] args) {
RedPacket rp = new RedPacket("大紅包");
}
}
運(yùn)行代碼,打開(kāi)一個(gè)發(fā)紅包的頁(yè)面??梢暂斎肟偨痤~,紅包個(gè)數(shù),留言信息。

點(diǎn)擊 塞錢(qián)進(jìn)紅包 按鈕,跳轉(zhuǎn)到下一頁(yè)面。

5. RedPacket 對(duì)象
RedPacket對(duì)象,設(shè)置群主名稱。setOwnerName(String ownerName) ,是字符串作為參數(shù)。我們只需要傳遞一個(gè)字符串即可。
public class RedPacketTest {
public static void main(String[] args) {
// 創(chuàng)建紅包對(duì)象
RedPacket rp = new RedPacket("大紅包");
// 設(shè)置群主名稱
rp.setOwnerName("我是群大大");
}
}
6. RedPacket 對(duì)象
設(shè)置紅包類(lèi)型。setOpenMode(OpenMode openMode) ,是接口作為參數(shù)。我們必須定義接口的實(shí)現(xiàn)類(lèi),重寫(xiě)接口中方法,并傳遞實(shí)現(xiàn)類(lèi)對(duì)象到 setOpenMode 方法中,方可設(shè)置完成。再觀察接口:
public interface OpenMode {
/**
* @param totalMoney 總金額,單位是"分"??偨痤~為方便計(jì)算,已經(jīng)轉(zhuǎn)換為整數(shù),單位為分。
* @param count 紅包個(gè)數(shù)
* @return ArrayList<Integer> 元素為各個(gè)紅包的金額值,所有元素的值累和等于總金額.
*
* 請(qǐng)將totalMoney,分成count分,保存到ArrayList<Integer>中,返回即可.
*/
public abstract ArrayList<Integer> divide(int totalMoney, int count);
}
普通紅包
打開(kāi)方式 Common。
public class Common implements OpenMode {
@Override
public ArrayList<Integer> divide(int totalMoney, int count) {
// 創(chuàng)建保存各個(gè)紅包金額的集合
ArrayList<Integer> list = new ArrayList<>();
// 計(jì)算平均金額
int avgMoney = totalMoney / count;
// 設(shè)置前面count‐1個(gè)人都是平均的金額
for (int i = 0; i < count ‐ 1; i++) {
list.add(avgMoney);
// 從總金額中減去已分配的金額,就是最后一個(gè)人剩余的金額
totalMoney ‐= avgMoney;
}
// 將剩余的金額設(shè)置給最后一個(gè)人
list.add(totalMoney);
return list;
}
}
發(fā)普通紅包
public class RedPacketTest {
public static void main(String[] args) {
// 創(chuàng)建紅包對(duì)象
RedPacket rp = new RedPacket("大紅包");
// 設(shè)置群主名稱
rp.setOwnerName("我是群大大");
// 設(shè)置紅包類(lèi)型
rp.setOpenMode(new Common()); // 普通紅包
}
}
拼手氣紅包
本質(zhì)上,手氣紅包就是把總金額 totalMoney 隨機(jī)分成指定的 count 份,所以必須規(guī)定每一份金額的取值范圍。如果范圍太小,可能導(dǎo)致后分配紅包金額特別大。反之范圍太大,可能導(dǎo)致后分配紅包金額為0,不夠分??梢?jiàn),取值范圍的定義規(guī)則,是手氣紅包的關(guān)鍵所在。
我們規(guī)定:每一份隨機(jī)金額范圍(除最后一份),最小值為1,最大值為當(dāng)前剩余平均金額的2倍 ,單位為"分"。
計(jì)算公式:
當(dāng)前剩余平均金額=剩余總金額/剩余紅包個(gè)數(shù)
舉例:總額為50元,發(fā)5個(gè)紅包。

小貼士:為方便表格中進(jìn)行運(yùn)算,此處,單位為"元"。程序中,建議換算為"分"進(jìn)行運(yùn)算。
Lucky:
手氣紅包,打開(kāi)方式 Lucky ,代碼如下:
public class Lucky implements OpenMode {
@Override
public ArrayList<Integer> divide(int totalMoney, int count) {
// 創(chuàng)建保存各個(gè)紅包金額的集合
ArrayList<Integer> list = new ArrayList<>();
// 定義循環(huán)次數(shù),總個(gè)數(shù)‐1次
int time = count ‐ 1;
// 創(chuàng)建隨機(jī)數(shù)對(duì)象
Random random = new Random();
// 循環(huán)分配
for (int i = 0; i < time; i++) {
/*
* 每次重新計(jì)算,生成隨機(jī)金額
* 隨機(jī)范圍: totalMoney / count * 2,totalMoney不斷的減少,
* count也不斷的減少,所以這是一個(gè)可變化的范圍.
*/
int money = random.nextInt(totalMoney / count * 2) + 1;
// 金額添加到集合
list.add(money);
// 總金額扣除已分配金額
totalMoney ‐= money;
// 紅包個(gè)數(shù)‐1
count‐‐;
}
// 剩余的金額,為最后一個(gè)紅包
list.add(totalMoney);
return list;
}
}
發(fā)紅包
public class RedPacketTest {
public static void main(String[] args) {
// 創(chuàng)建紅包對(duì)象
RedPacket rp = new RedPacket("大紅包");
// 設(shè)置群主名稱
rp.setOwnerName("我是群大大");
// 設(shè)置紅包類(lèi)型,二選一
// rp.setOpenMode(new Common()); // 普通紅包
rp.setOpenMode(new Lucky()); // 手氣紅包
}
}
總結(jié)
通過(guò) 發(fā)紅包 案例,我將之前所學(xué)過(guò)的各種類(lèi)和方法總結(jié)起來(lái),如下:
1. 基礎(chǔ)語(yǔ)法。
2. 一些基本的類(lèi)的方法。
3. 案例體現(xiàn)了面向?qū)ο笾^承。
4. 接口作為參數(shù)的使用。
5. 簡(jiǎn)化接口的使用方式。
相信每位讀者,都會(huì)有自己的思考和答案。也相信各位讀者,隨著開(kāi)發(fā)經(jīng)驗(yàn)的豐富,對(duì)于技術(shù)的理解會(huì)更加深入,對(duì)技術(shù)的運(yùn)用會(huì)更加純熟。通過(guò)對(duì)大量案例的不斷積累,最終寫(xiě)出屬于你自己的程序,成為一名真正的coder。感謝大家的閱讀,技術(shù)的道路上,這只是一個(gè)開(kāi)始!謝謝大家!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Security OAuth2 token權(quán)限隔離實(shí)例解析
這篇文章主要介紹了Spring Security OAuth2 token權(quán)限隔離實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
Java精品項(xiàng)目瑞吉外賣(mài)之登陸的完善與退出功能篇
這篇文章主要為大家詳細(xì)介紹了java精品項(xiàng)目-瑞吉外賣(mài)訂餐系統(tǒng),此項(xiàng)目過(guò)大,分為多章獨(dú)立講解,本篇內(nèi)容為新增菜品和分頁(yè)查詢功能的實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
SpringMVC訪問(wèn)靜態(tài)資源的三種方式小結(jié)
這篇文章主要介紹了SpringMVC訪問(wèn)靜態(tài)資源的三種方式小結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
Spring注解驅(qū)動(dòng)之ApplicationListener用法解讀
這篇文章主要介紹了Spring注解驅(qū)動(dòng)之ApplicationListener用法解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
SpringAOP 設(shè)置注入的實(shí)現(xiàn)步驟
這篇文章主要介紹了SpringAOP 設(shè)置注入的實(shí)現(xiàn)步驟,幫助大家更好的理解和學(xué)習(xí)使用Spring框架,感興趣的朋友可以了解下2021-05-05
Java獲取視頻時(shí)長(zhǎng)及截取幀截圖詳解
這篇文章主要介紹了Java獲取視頻時(shí)長(zhǎng)及截取幀截圖詳解,以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。,需要的朋友可以參考下2019-06-06
JDK動(dòng)態(tài)代理提高代碼可維護(hù)性和復(fù)用性利器
這篇文章主要為大家介紹了JDK動(dòng)態(tài)代理提高代碼可維護(hù)性和復(fù)用性利器,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
java性能調(diào)優(yōu)System的gc垃圾回收方法
這篇文章主要為大家介紹了java性能調(diào)優(yōu)System的gc垃圾回收方法示例解析有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03

