模拟实现简易的移动用户资费统计系统逻辑,具体需求如下:
? 普通用户资费标准如下(不考虑漫游和长途):
【基准资费】
无月租费用。
通话费:0.6元 / 分钟(仅拨打收费,接听免费)
短信费:0.1元 / 条
数据费:5元/ M
【优惠套餐】
话费套餐 :月功能费 20元,最多可拨打60分钟电话,超出时间按照
0.5元 / 分钟计费。
短信套餐 :月功能费10元,最多可发送200条短信,超出条数按照
0.1元 / 条计费。
数据套餐 :月功能费20元,最多可获50M的流量,超出流量按照
3元 / M 计费。
注:用户可以选择多种套餐,各功能(通话、短信、数据)计费时,如已选择对应套餐,则按套餐标准计费;如未选择对应套餐,则按对应的基准资费计费。
? 新用户入网。
① 对于新入网的普通用户,入网当月赠送如下服务:免费拨打60分钟
电话,免费发送200条短信,免费获得50M流量。超出赠送的部分
按照普通用户基准资费进行计费。
② 对于新入网的VIP用户,入网当月赠送如下服务:免费拨打200分
钟电话,免费发送200条短信,免费获得100M数据流量。超出赠送
的部分按照VIP用户基准资费进行计费(注意:需按入网天数计算月
租费用)。
? 每月为用户计算一次账单,用户订制的套餐信息和账单信息采用文件方式进行存储(提示:可使用java中的Properties API进行文件操作)。
? 用户可自由订制或退订所属用户类型的套餐,并从下月起生效。
package my.postage;
import java.io.*;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class mypstage {
/**
* @param args
*/
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stubD
int monthDay=0;
//新用户入网
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new NewUserCreator(),
0, 30, TimeUnit.SECONDS);
//定制和退订套餐
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new PacketSelect(),
60, 50, TimeUnit.SECONDS);
//用户打电话,发信息或者上网
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new RandomUser(),
300, 20, TimeUnit.SECONDS);
}// main
//----------------------------------------------------------------------
static void saveAllTypical(Hashtable userHash){
Enumeration e =userHash.elements();
Enumeration userKey = userHash.keys();
Properties pro = new Properties();
while(userKey.hasMoreElements()){
Integer key =(Integer)userKey.nextElement();
TypicalUser user=(TypicalUser)e.nextElement();
//TypicalUser user =(TypicalUser)typicalHash.get(key);
user.billGeneration();
String fileName = String.valueOf(key)+user.userName+".txt";
System.out.println(user.userName+"---total---"+user.bill.totalFee);
user.saveToFile(fileName);
user.cancelNewUser();
System.out.println("save in "+fileName);
}//while
}//end void
//----------------------------------------------------------------------
static void saveAllVip(Hashtable userHash){
Enumeration e =userHash.elements();
Enumeration userKey = userHash.keys();
Properties pro = new Properties();
while(userKey.hasMoreElements()){
Integer key =(Integer)userKey.nextElement();
user.billGeneration();
String fileName = String.valueOf(key)+user.userName+".txt";
System.out.println(user.userName+"---total---"+user.bill.totalFee);
user.saveToFile(fileName);
System.out.println("save in "+fileName);
user.cancelNewUser();
}//while
}//end void
}//class
package my.postage;
import java.io.*;
import java.util.*;
import java.util.concurrent.Executors;
//新用户入网,生成的客户存入Hash中,并把用户信息保存在文件中
class NewUserCreator implements Runnable{
static Hashtable vipHash = new Hashtable();
static Hashtable typicalHash = new Hashtable();
static int typKey = 1;
static int vipKey = 1;
public void run(){
RandomGenerator generator = new RandomGenerator();
if(generator.userType==1){
VipUser vipUser =new VipUser("VipUserName"+String.valueOf(vipKey),generator.vipPacket);
vipHash.put(vipKey,vipUser);
vipUser.saveToFile( "VipUserInfo"+String.valueOf(vipKey)+".txt");
System.out.println("有新的VIP客户入网!序号是:"+vipKey);
System.out.println("用户定制:"+ "套餐1= "+String.valueOf(typPacket&0x1)+" 套餐2= "+String.valueOf(typPacket>>1&0x1));
vipKey++;
}
else{
TypicalUser typUser=new TypicalUser("TypUserName"+String.valueOf(typKey),generator.typPacket);
typicalHash.put(typKey,typUser);
typUser.saveToFile("TypUserInfo"+String.valueOf(typKey)+".txt");
System.out.println("有新的普通客户入网!序号是:"+typKey);
System.out.print("用户定制:"+"电话套餐="+ String.valueOf(typPacket&0x1));
System.out.println(" 短信套餐="+String.valueOf( typPacket>>1&0x1)+" 网络套餐="+ String.valueOf(typPacket>>2&0x1));
typKey++;
}
}//run
}//class
//用户修改套餐,并把修改后的套餐信息保存在文件中
class PacketSelect implements Runnable{
public void run(){
RandomGenerator generator = new RandomGenerator();
if(generator.userType==1){
int randomKey = new Random().nextInt(NewUserCreator.vipHash.size()-1)+1;
VipUser vipUser =(VipUser)NewUserCreator.vipHash.get(randomKey);
vipUser.setVipCustomized(generator.vipPacket);
vipUser.saveToFile("VipUserInfo"+String.valueOf(randomKey)+".txt");
System.out.println("<VIP客户>修改套餐!序号是:"+randomKey);
System.out.println("新套餐:"+ "套餐1= "+String.valueOf(generator.typPacket&0x1)+" 套餐2= "+String.valueOf(generator.typPacket>>1&0x1));
}
else{
int randomKey = new Random().nextInt(NewUserCreator.typicalHash.size())+1;
TypicalUser typUser =(TypicalUser)NewUserCreator.typicalHash.get(randomKey);
typUser.setTypicalCustomized(generator.typPacket);
typUser.saveToFile( "TypUserInfo"+String.valueOf(randomKey)+".txt");
System.out.println("《普通客户》修改套餐!序号是:"+randomKey);
System.out.print("新套餐:"+"电话套餐="+ String.valueOf(generator.typPacket&0x1));
System.out.println(" 短信套餐="+String.valueOf( generator.typPacket>>1&0x1)+" 网络套餐="+ String.valueOf(generator.typPacket>>2&0x1));
}
}//run
}//class
//客户打电话,发短信或上网,计算数据并存储
class RandomUser implements Runnable{
public void run(){
RandomGenerator generator = new RandomGenerator();
if(generator.userType==1){
int randomKey = new Random().nextInt(NewUserCreator.vipHash.size())+1;//随机生成vip用户的关键字
VipUser user =(VipUser)NewUserCreator.vipHash.get(randomKey);//获取该用户的信息
infoSelect(generator.infoType,user,"VIP客户,序号是:"+randomKey);
}
else{
int randomKey = new Random().nextInt(NewUserCreator.typicalHash.size())+1;
TypicalUser user =(TypicalUser)NewUserCreator.typicalHash.get(randomKey);
infoSelect(generator.infoType,user,"普通客户,序号是:"+randomKey);
}
}//void
void infoSelect(int infoType,User user,String userInfo){
switch(infoType){
case 0:
String callInfo ="打电话";
user.userData.callUsed += callTimeCal(userInfo);
System.out.println(userInfo+callInfo+"使用记录已经计入账户!");
break;
case 1:
String messageInfo ="发短信";
user.userData.messageUsed += messageCal(userInfo);
System.out.println(userInfo+messageInfo+"使用记录已经计入账户!");
break;
case 2:
String netInfo ="上网";
user.userData.dataUsed += internetCal(userInfo);
System.out.println(userInfo+netInfo+"使用记录已经计入账户!");
break;
}
}
synchronized float callTimeCal(String userInfo){
System.out.println(userInfo+ "开始打电话!");
int maxRandom = 600000 - 60000;
int callTime = new Random().nextInt(maxRandom)+1 + 60000;
try {
Thread.sleep(callTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(userInfo+ "挂断电话!" + "总共耗时" + callTime/1000 + "秒");
return callTime/1000;
}//void
synchronized float messageCal(String userInfo){
int userType = new Random().nextInt(1) ;//0-typ,1 -vip
System.out.println(userInfo + "正在发短信!");
int messageNum = new Random().nextInt(9)+1 ;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(userInfo + "已发送短信" + "总发送" + messageNum + "条");
return messageNum;
}//void
synchronized float internetCal(String userInfo){
System.out.println(userInfo + "正在上网!");
int data = new Random().nextInt(19)+1 ;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(userInfo +"停止上网!" + "获取数据流量" + data*50 + "K");
return data*50;
}//void
}//class
class RandomGenerator{
int vipPacket = new Random().nextInt(3);//0,1,2
int typPacket = new Random().nextInt(8);//000-111
int userType = new Random().nextInt(2) ;//0-typ,1 -vip 随机生成用户类型
int infoType = new Random().nextInt(3);//0-call,1-message,2-data随机生成数据信息
}
package my.postage;
import java.util.Calendar;
import java.util.Random;
//定义账单类,该类包含基本费,电话费,信息费和数据费,以及总费用,
//提供计算各种费用的方法;
class Bill{
float baseFee=0;
float callFee=0;
float messageFee=0;
float dataFee=0;
float totalFee=0;
//--------------------------------calculate total
float calculateBillTotal(){
return this.baseFee+this.callFee+this.messageFee+this.dataFee; }
} // class
//定义用户数据类,包含已经使用的电话时间,使用的信息,使用的数据以及使用的日期。
//提供存储数据的方法
public class UserData{
float callUsed;
float messageUsed;
float dataUsed;
float dateUsed;
//-----------------------------------
void setUserData(float[] dataBeUsed){
this.callUsed = dataBeUsed[0];
this.messageUsed = dataBeUsed[1];
this.dataUsed = dataBeUsed[2];
this.dateUsed = dataBeUsed[3];}
}//class
//基本用户
class User {
String userName;
boolean isNewUser;
int addMonth;
UserData userData = new UserData();
Bill bill=new Bill();
//---------------------------------------------------------
User(String userName){
addMonth=Calendar.MONTH+1;
isNewUser = true;
this.userName = userName;
}
//----------------------------------------------------------
void cancelNewUser(){
//if(addMonth!=Calendar.MONTH+1)
isNewUser = false;}
}
package my.postage;
import java.io.*;
import java.util.*;
typical用户class
///
class TypicalUser extends User{
int callPacket;
int messagePacket;
int dataPacket;
int typPacket;
//构造函数
TypicalUser(String userName,int typPacket){
super(userName);
this.setTypicalCustomized(typPacket);
}//
//typical用户定制退订套餐方法
void setTypicalCustomized(int typPacket){
this.callPacket = typPacket&0x1;
this.messagePacket=(typPacket>>1)&0x1;
this.dataPacket=(typPacket>>2)&0x1;
}//void
//typical用户计算话费方法
void billGeneration(){
if(isNewUser){
userData.callUsed-=60;
userData.messageUsed -=200;
userData.dataUsed -= 50;
}
if(callPacket==1){
bill.baseFee+=20;
if(userData.callUsed>60)
bill.callFee=(userData.callUsed-60)*0.5f;
}
else
if(userData.callUsed>0)
bill.callFee=(userData.callUsed)*0.6f;
if(messagePacket==1){
bill.baseFee+=10;
if(userData.messageUsed>200)
bill.messageFee =(userData.messageUsed-200)*0.1f;
}
else
if(userData.messageUsed>0)
bill.messageFee =(userData.messageUsed)*0.1f;
if(dataPacket==1){
bill.baseFee+=20;
if(userData.dataUsed>50)
bill.dataFee =(userData.dataUsed-50)*3;
}
else
if(userData.dataUsed>0)
bill.dataFee =(userData.dataUsed)*5;
bill.totalFee=bill.calculateBillTotal();
}//void
//保存用户定制信息到文件中
void saveToFile(String fileName){
//FileInputStream a = new FileInputStream(fileName);
Properties pro = new Properties();
try{
pro.load(new FileInputStream(fileName));
}catch(Exception e)
{
pro.setProperty("userName",String.valueOf(userName));
pro.setProperty("callPacket",String.valueOf(callPacket));
pro.setProperty("messagePacket",String.valueOf(messagePacket));
pro.setProperty("dataPacket",String.valueOf(dataPacket));
pro.setProperty("addMonth",String.valueOf(addMonth));
pro.setProperty("callUsed",String.valueOf(userData.callUsed));
pro.setProperty("messageUsed",String.valueOf(userData.messageUsed));
pro.setProperty("dataUsed",String.valueOf(userData.dataUsed));
pro.setProperty("dateUsed",String.valueOf(userData.dateUsed));
pro.setProperty("baseFee",String.valueOf(bill.baseFee));
pro.setProperty("callFee",String.valueOf(bill.callFee));
pro.setProperty("messageFee",String.valueOf(bill.messageFee));
pro.setProperty("dataFee",String.valueOf(bill.dataFee));
pro.setProperty("totalFee",String.valueOf(bill.totalFee));
}
try{
pro.store(new FileOutputStream(fileName),"Typical User Customized Info");
//System.out.println( "用户信息保存的文件名是:"+fileName);
}catch (Exception e)
{
e.printStackTrace();
}
}//void
}// class
package my.postage;
import java.io.*;
import java.util.*;
//
//VIP用户class
/
class VipUser extends User{
//enum VipPacketType {NOPACKAGE,PACKAGE1,PACKAGE2};
int vipPacketType;
构造函数
VipUser(String userName,int vipPacketType){
super(userName);
setVipCustomized(vipPacketType);
}
VIP用户定制退订套餐方法
void setVipCustomized(int vipPacketType){
this.vipPacketType =vipPacketType; }
VIP用户计算话费方法
void billGeneration(){
if(isNewUser){
userData.callUsed-=200;
userData.messageUsed -=200;
userData.dataUsed -= 100;}
switch(vipPacketType){
case 0:
bill.baseFee=userData.dateUsed*2;
if(userData.callUsed>0)bill.callFee=userData.callUsed*0.4f;
else bill.callFee =0;
if(userData.messageUsed>0)bill.messageFee =userData.messageUsed*0.1f;
else bill.messageFee=0;
if(userData.dataUsed>0)bill.dataFee =userData.dataUsed*3;
else bill.dataFee=0;
break;
case 1:
bill.baseFee=100;
if(userData.callUsed>750)
bill.callFee=(userData.callUsed-750)*0.3f;
if(userData.messageUsed>200)
bill.messageFee =(userData.messageUsed-200)*0.1f;
if(userData.dataUsed>100)
bill.dataFee =(userData.dataUsed-100)*1;
break;
case 2:
bill.baseFee=200;
if(userData.callUsed>2000)
bill.callFee=(userData.callUsed-2000)*0.2f;
if(userData.messageUsed>500)
bill.messageFee =(userData.messageUsed-500)*0.1f;
if(userData.dataUsed>300)
bill.dataFee =(userData.dataUsed-300)*0.5f;
break;
default:
System.out.println("calculate无效");
return;}
bill.totalFee = bill.calculateBillTotal();
}//void
//保存vip用户信息到文件中
void saveToFile(String fileName){
Properties pro = new Properties();
try{
pro.load(new FileInputStream(fileName));
}catch(Exception e)
{
pro.setProperty("userName",String.valueOf(userName));
pro.setProperty("vipPacket",String.valueOf(vipPacketType));
pro.setProperty("addMonth",String.valueOf(addMonth));
pro.setProperty("callUsed",String.valueOf(userData.callUsed));
pro.setProperty("messageUsed",String.valueOf(userData.messageUsed));
pro.setProperty("dataUsed",String.valueOf(userData.dataUsed));
pro.setProperty("dateUsed",String.valueOf(userData.dateUsed));
pro.setProperty("baseFee",String.valueOf(bill.baseFee));
pro.setProperty("callFee",String.valueOf(bill.callFee));
pro.setProperty("messageFee",String.valueOf(bill.messageFee));
pro.setProperty("dataFee",String.valueOf(bill.dataFee));
pro.setProperty("totalFee",String.valueOf(bill.totalFee));
}
try{
pro.store(new FileOutputStream(fileName),"Vip User Customized Info");
//System.out.println( "用户信息保存的文件名是:"+fileName);
}catch (Exception e)
{
e.printStackTrace();
}
}//void
}//class
------------------------------------------------------------------------------
有新的普通客户入网!序号是:1
有新的VIP客户入网!序号是:1
有新的VIP客户入网!序号是:2
有新的普通客户入网!序号是:2
有新的VIP客户入网!序号是:3
有新的VIP客户入网!序号是:4
有新的普通客户入网!序号是:3
有新的普通客户入网!序号是:4
有新的普通客户入网!序号是:5
有新的普通客户入网!序号是:6
有新的VIP客户入网!序号是:5
普通客户,序号是:6正在发短信!
普通客户,序号是:6已发送短信总发送6条
普通客户,序号是:6发短信使用记录已经计入账户!
VIP客户,序号是:1正在上网!
VIP客户,序号是:1停止上网!获取数据流量700K
VIP客户,序号是:1上网使用记录已经计入账户!
有新的普通客户入网!序号是:7
VIP客户,序号是:3正在发短信!
VIP客户,序号是:3已发送短信总发送1条
VIP客户,序号是:3发短信使用记录已经计入账户!
有新的普通客户入网!序号是:8
普通客户,序号是:5开始打电话!
有新的普通客户入网!序号是:9
有新的VIP客户入网!序号是:6
有新的VIP客户入网!序号是:7
有新的VIP客户入网!序号是:8
有新的普通客户入网!序号是:10
有新的VIP客户入网!序号是:9
有新的普通客户入网!序号是:11
有新的普通客户入网!序号是:12
有新的VIP客户入网!序号是:10
有新的普通客户入网!序号是:13
有新的VIP客户入网!序号是:11
有新的普通客户入网!序号是:14
普通客户,序号是:5挂断电话!总共耗时379秒
普通客户,序号是:5打电话使用记录已经计入账户!
VIP客户,序号是:8正在上网!
VIP客户,序号是:8停止上网!获取数据流量600K
VIP客户,序号是:8上网使用记录已经计入账户!
普通客户,序号是:1正在发短信!
普通客户,序号是:1已发送短信总发送9条
普通客户,序号是:1发短信使用记录已经计入账户!
普通客户,序号是:3正在发短信!
普通客户,序号是:3已发送短信总发送5条
普通客户,序号是:3发短信使用记录已经计入账户!
普通客户,序号是:4开始打电话!
有新的VIP客户入网!序号是:12
有新的普通客户入网!序号是:15
有新的普通客户入网!序号是:16
普通客户,序号是:4挂断电话!总共耗时80秒
普通客户,序号是:4打电话使用记录已经计入账户!
VIP客户,序号是:9正在发短信!
VIP客户,序号是:9已发送短信总发送7条
VIP客户,序号是:9发短信使用记录已经计入账户!
普通客户,序号是:3开始打电话!
有新的VIP客户入网!序号是:13
有新的普通客户入网!序号是:17
有新的VIP客户入网!序号是:14
有新的普通客户入网!序号是:18
有新的普通客户入网!序号是:19
普通客户,序号是:3挂断电话!总共耗时155秒
普通客户,序号是:3打电话使用记录已经计入账户!
普通客户,序号是:3开始打电话!
有新的VIP客户入网!序号是:15
有新的普通客户入网!序号是:20
有新的VIP客户入网!序号是:16
有新的VIP客户入网!序号是:17
有新的普通客户入网!序号是:21
有新的VIP客户入网!序号是:18
有新的VIP客户入网!序号是:19
有新的VIP客户入网!序号是:20
有新的普通客户入网!序号是:22
有新的普通客户入网!序号是:23
有新的普通客户入网!序号是:24
有新的普通客户入网!序号是:25
有新的普通客户入网!序号是:26
有新的VIP客户入网!序号是:21
有新的VIP客户入网!序号是:22
有新的普通客户入网!序号是:27
有新的普通客户入网!序号是:28