java基础综合练习(嗖嗖移动)

功能列表:

服务器端代码:

 1 package cn.luoxue.server;
 2 
 3 import java.io.IOException;
 4 import java.net.DatagramPacket;
 5 import java.net.DatagramSocket;
 6 import java.net.InetAddress;
 7 
 8 public class UDPServer {
 9     public static void main(String[] args) throws IOException {
10         DatagramSocket socket = new DatagramSocket(8800);
11         DatagramPacket packet = null;
12         byte[] data = null;
13         int count = 0;
14         System.out.println("***客服静候您的咨询***");
15         while(true){
16             data = new byte[1024];//创建字节数组,指定接收的数据包的大小
17             packet = new DatagramPacket(data, data.length);
18             socket.receive(packet);//此方法在接收到数据报之前会一直阻塞
19             Thread thread = new Thread(new UDPThread(socket, packet));
20             thread.start();
21             count++;
22             System.out.println("服务器端被连接过的次数:"+count);
23             InetAddress address = packet.getAddress();
24             System.out.println("当前客户端的IP为:"+address.getHostAddress());
25             
26         }
27         
28     }
29 }


 多线程代码:

package cn.luoxue.server;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPThread implements Runnable{
    
    DatagramSocket socket = null;
    DatagramPacket packet = null;
    

    public UDPThread(DatagramSocket socket,DatagramPacket packet) {
        this.socket = socket;
        this.packet = packet;
    }

    @Override
    public void run() {
        String info = null;
        InetAddress address = null;
        int port = 8800;
        byte[] data2 = null;
        DatagramPacket packet2 = null;
        try {
            info = new String(packet.getData(), 0, packet.getLength());
            System.out.println("我是服务器,客户端说:"+info);
            
            address = packet.getAddress();
            port = packet.getPort();
            if(info.equals("886")){
                data2 = "好的,回聊".getBytes();
            }else if(info.equals("美女你好问个问题")){
                data2 = "先生,你想问什么呢".getBytes();
            }else if(info.equals("你认为明天是什么天气")){
                data2 = "那还用说,当然是晴天!".getBytes();
            }else if(info.equals("适合爬山吗")){
                data2 = "毫无争议绝对适合".getBytes();
            }else if(info.equals("最高的山峰是哪个")){
                data2 = "珠穆朗玛峰!".getBytes();
            }else{
                data2 = "你说啥?风大听不到!".getBytes();
            }
                
            packet2 = new DatagramPacket(data2, data2.length, address, port);
            socket.send(packet2);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //socket.close();不能关闭         
    }

}

实体类代码:

package cn.luoxue.entityclass;

import cn.luoxue.interfaces.NetService;
import cn.luoxue.search_The_mobile_lobby.MobileCard;

/**
 * 网虫套餐类
 * @author 三文鱼的回流
 *
 */
public class NetPackage extends ServicePackage implements NetService {
    private int flow; //上网流量
    
    public NetPackage() {
        super();
        // TODO Auto-generated constructor stub
    }
    
    public NetPackage(double price, int flow) {
        super(price);
        this.flow = flow;
    }

    public int getFlow() {
        return flow;
    }

    public void setFlow(int flow) {
        this.flow = flow;
    }

    @Override
    //返回使用流量数
        public int netPlay(int flow, MobileCard card) throws Exception {
            int temp = flow;
            for(int i = 0; i < flow; i++){
                if(this.flow - card.getRealFlow() >= 1){
                    //第一种情况:流量剩余够 1 MB
                    card.setRealFlow(card.getRealFlow() + 1);
                }else if(card.getMoney() >= 0.1){
                    //第二种情况:套餐内流量已经用完,剩下话费够支付 1 MB的流量
                    card.setRealFlow(card.getRealFlow() + 1); //实际短信数加 1 条
                    //账户余额消费0.1元,(1MB流量)
                    card.setMoney(card.getMoney() - 0.1);
                    card.setConsumAmount(card.getConsumAmount() + 0.1);  //当月消费金额 + 0.1
                }else{
                    temp = i; //记录使用流量多少MB
                    throw new Exception("流量已经使用" + i + "MB,您的余额不足,请充值后再使用!");
                    //System.err.println("流量已经使用" + i + "MB,您的余额不足,请充值后再使用!");
                }
            }
            return temp;
        }

    @Override
    public void showInfo() {
        System.out.println("网虫套餐:上网流量为:" + (this.flow * 1.0 / 1024) + "GB/月," + "资费为:" + super.getPrice() + "元/月");
    }

}
package cn.luoxue.entityclass;

import cn.luoxue.interfaces.CallService;
import cn.luoxue.interfaces.NetService;
import cn.luoxue.interfaces.SendService;
import cn.luoxue.search_The_mobile_lobby.MobileCard;

/**
 * 超人套餐类
 * @author 三文鱼的回流
 *
 */
public class SuperPackage extends ServicePackage implements SendService,
        NetService, CallService {
    private int talkTime; //通话时长
    private int smsCount; //短信条数
    private int flow; //上网流量
    
    public SuperPackage() {
        super();
        // TODO Auto-generated constructor stub
    }

    public SuperPackage(double price, int talkTime, int smsCount, int flow) {
        super(price);
        this.talkTime = talkTime;
        this.smsCount = smsCount;
        this.flow = flow;
    }

    public int getTalkTime() {
        return talkTime;
    }

    public void setTalkTime(int talkTime) {
        this.talkTime = talkTime;
    }

    public int getSmsCount() {
        return smsCount;
    }

    public void setSmsCount(int smsCount) {
        this.smsCount = smsCount;
    }

    public int getFlow() {
        return flow;
    }

    public void setFlow(int flow) {
        this.flow = flow;
    }

    @Override
    //返回通话时长
    public int call(int minCount, MobileCard card) throws Exception{
        int temp = minCount;
        for(int i = 0; i < minCount; i++){
            if(this.talkTime - card.getRealTalkTime() >= 1){
                //第一种情况:套餐剩余通话时长可以支持1分钟通话
                card.setRealTalkTime(card.getRealTalkTime() + 1);
            }else if(card.getMoney() >= 0.2){
                //第二种情况:套餐通话时长已用完,账户余额可以支付1分钟通话,使用账户余额支付
                card.setRealTalkTime(card.getRealTalkTime() + 1); //实际使用通话时长1分钟
                //账户余额消费0.2元(1分钟 额外通话)
                card.setMoney(card.getMoney() - 0.2);
                card.setConsumAmount(card.getConsumAmount() + 0.2);  //当月消费金额 + 0.2
            }else{
                temp = i; //记录实际通话分钟数
                throw new Exception("本次已经通话" + i + "分钟,您的余额不足,请充值后再使用!");
                //System.err.println("本次已经通话" + i + "分钟,您的余额不足,请充值后再使用!");
            }
        }
        return temp;
    }

    @Override
    //返回使用流量数
    public int netPlay(int flow, MobileCard card) throws Exception {
        int temp = flow;
        for(int i = 0; i < flow; i++){
            if(this.flow - card.getRealFlow() >= 1){
                //第一种情况:流量剩余够 1 MB
                card.setRealFlow(card.getRealFlow() + 1);
            }else if(card.getMoney() >= 0.1){
                //第二种情况:套餐内流量已经用完,剩下话费够支付 1 MB的流量
                card.setRealFlow(card.getRealFlow() + 1); //实际短信数加 1 条
                //账户余额消费0.1元,(1MB流量)
                card.setMoney(card.getMoney() - 0.1);
                card.setConsumAmount(card.getConsumAmount() + 0.1);  //当月消费金额 + 0.1
            }else{
                temp = i; //记录使用流量多少MB
                throw new Exception("流量已经使用" + i + "MB,您的余额不足,请充值后再使用!");
            }
        }
        return temp;
    }

    @Override
    //返回实际发送短信条数
    public int send(int count, MobileCard card) throws Exception {
        int temp = count;
        for(int i = 0; i < count; i++){
            if(this.smsCount - card.getRealSMSCount() >= 1){
                //第一种情况:套餐剩余短信数能够发送一个短信
                card.setRealSMSCount(card.getRealSMSCount() + 1);
            }else if(card.getMoney() >= 0.1){
                //第二种情况:套餐内短信已经用完,剩下话费能够允许发一条短信
                card.setRealSMSCount(card.getRealSMSCount() + 1); //实际短信数加 1 条
                //账户余额消费0.1元,(一条短信)
                card.setMoney(card.getMoney() - 0.1);
                card.setConsumAmount(card.getConsumAmount() + 0.1);  //当月消费金额 + 0.1
            }else{
                temp = i; //记录发短信条数
                throw new Exception("短信已经发送" + i + "条,您的余额不足,请充值后再使用!");
            }
        }
        return temp;
    }

    @Override
    public void showInfo() {
        System.out.println("超人套餐:通话时长为:" + this.talkTime + "分钟/月," + "短信条数为:" + this.smsCount + "条/每月," + "上网流量为:" + (this.flow * 1.0 / 1024) + "GB/月," + "资费为:" + super.getPrice() + "元/月" );
    }
}
package cn.luoxue.entityclass;

import cn.luoxue.interfaces.CallService;
import cn.luoxue.interfaces.SendService;
import cn.luoxue.search_The_mobile_lobby.MobileCard;

/**
 * 话唠套餐类
 * @author 三文鱼的回流
 *
 */
public class TalkPackage extends ServicePackage implements CallService, SendService {
    private int talkTime;//通话时长
    private int smsCount;//短信条数
    
    public TalkPackage() {
        super();
    }
    
    public TalkPackage(double price, int talkTime, int smsCount) {
        super(price);
        this.talkTime = talkTime;
        this.smsCount = smsCount;
    }
    
    public int getTalkTime() {
        return talkTime;
    }

    public void setTalkTime(int talkTime) {
        this.talkTime = talkTime;
    }

    public int getSmsCount() {
        return smsCount;
    }

    public void setSmsCount(int smsCount) {
        this.smsCount = smsCount;
    }

    @Override
    //返回通话时长
    public int call(int minCount, MobileCard card) throws Exception{
        int temp = minCount;
        for(int i = 0; i < minCount; i++){
            if(this.talkTime - card.getRealTalkTime() >= 1){
                //第一种情况:套餐剩余通话时长可以支持1分钟通话
                card.setRealTalkTime(card.getRealTalkTime() + 1);
            }else if(card.getMoney() >= 0.2){
                //第二种情况:套餐通话时长已用完,账户余额可以支付1分钟通话,使用账户余额支付
                card.setRealTalkTime(card.getRealTalkTime() + 1); //实际使用通话时长1分钟
                //账户余额消费0.2元(1分钟 额外通话)
                card.setMoney(card.getMoney() - 0.2);
                card.setConsumAmount(card.getConsumAmount() + 0.2);  //当月消费金额 + 0.2
            }else{
                temp = i; //记录实际通话分钟数
                throw new Exception("本次已经通话" + i + "分钟,您的余额不足,请充值后再使用!");
            }
        }
        return temp;
    }
    
    @Override
    //返回实际发送短信条数
        public int send(int count, MobileCard card) throws Exception {
            int temp = count;
            for(int i = 0; i < count; i++){
                if(this.smsCount - card.getRealSMSCount() >= 1){
                    //第一种情况:套餐剩余短信数能够发送一个短信
                    card.setRealSMSCount(card.getRealSMSCount() + 1);
                }else if(card.getMoney() >= 0.1){
                    //第二种情况:套餐内短信已经用完,剩下话费能够允许发一条短信
                    card.setRealSMSCount(card.getRealSMSCount() + 1); //实际短信数加 1 条
                    //账户余额消费0.1元,(一条短信)
                    card.setMoney(card.getMoney() - 0.1);
                    card.setConsumAmount(card.getConsumAmount() + 0.1);  //当月消费金额 + 0.1
                }else{
                    temp = i; //记录发短信条数
                    throw new Exception("短信已经发送" + i + "条,您的余额不足,请充值后再使用!");
                    //System.err.println("短信已经发送" + i + "条,您的余额不足,请充值后再使用!");
                }
            }
            return temp;
        }
    
    @Override
    public void showInfo() {
        System.out.println("话唠套餐:通话时长为:" + this.talkTime + "分钟/月,短信条数为:" + this.smsCount + "条/月,资费为:" + super.getPrice() + "元/月" );
    }

    

}
package cn.luoxue.entityclass;
/**
 * 资费套餐类 ,是话唠、网虫、超人套餐的父类
 * @author 三文鱼的回流
 *
 */
public abstract class ServicePackage {
    private double price; //月资费
    
    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public ServicePackage() {
        super();
        // TODO Auto-generated constructor stub
    }

    public ServicePackage(double price) {
        super();
        this.price = price;
    }

    public abstract void showInfo();
    
}

接口代码:

package cn.luoxue.interfaces;

import cn.luoxue.search_The_mobile_lobby.MobileCard;

/**
 * 接口 上网服务
 * @author 三文鱼的回流
 *
 */
public interface NetService {
    public abstract int netPlay(int flow, MobileCard card) throws Exception;
}
package cn.luoxue.interfaces;

import cn.luoxue.search_The_mobile_lobby.MobileCard;

/**
 *接口  通话服务
 * @author 三文鱼的回流
 *
 */
public interface CallService {
    public abstract int call (int minCount, MobileCard card) throws Exception;
}
package cn.luoxue.interfaces;

import cn.luoxue.search_The_mobile_lobby.MobileCard;

/**
 * 接口 短信服务
 * @author 三文鱼的回流
 *
 */
public interface SendService {
    public abstract int send(int count, MobileCard card) throws Exception; 
}

工具类:

package cn.luoxue.search_The_mobile_lobby;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;

import cn.luoxue.entityclass.NetPackage;
import cn.luoxue.entityclass.ServicePackage;
import cn.luoxue.entityclass.SuperPackage;
import cn.luoxue.entityclass.TalkPackage;
import cn.luoxue.interfaces.CallService;
import cn.luoxue.interfaces.NetService;
import cn.luoxue.interfaces.SendService;

/**
 * 工具类
 * @author Administrator
 *
 */
public class CardUtil {
    //Common common = new Common();
    protected static Map<String, MobileCard> cards = new HashMap<String, MobileCard>(); //已注册嗖嗖移动用户列表
    protected static Map<String, List<ConsumInfo>> consumInfos = new HashMap<String, List<ConsumInfo>>(); //所有卡号的消费记录列表
    protected static Map<Integer, Scene> scenes = new HashMap<Integer, Scene>();//使用场景列表
    protected static Scene scene0 = new Scene("通话", 90, "问候客户,谁知其如此难缠,通话90分钟");
    protected static Scene scene1 = new Scene("通话", 30, "询问妈妈身体状况,本地通话30分钟");
    protected static Scene scene2 = new Scene("短信", 5, "参与环境保护实施方案问卷调查,发送短信5条");
    protected static Scene scene3 = new Scene("短信", 50, "通知朋友手机换号,发送短信50条");
    protected static Scene scene4 = new Scene("上网", 1024, "和女朋友用微信视频聊天,使用流量1GB");
    protected static Scene scene5 = new Scene("上网", 2 * 1024, "晚上手机在线看韩剧,不留神睡着啦!使用2GB");
    protected static Scanner input = new Scanner(System.in);

    public CardUtil() {
        super();
        // TODO Auto-generated constructor stub
    }

    
    
    /**
     *注册新卡
     * @param card
     */
    public static void addCard(MobileCard card){
        cards.put(card.getCardNumber(), card);
    }
    
    
    /**
     *话费充值
     * @param number
     */
    public static void chargeMoney(String number){
        System.out.println("请输入要充值的金额(不少于50元):");
        while(true){
            double money = 0.0;
            while(true){
                Scanner input = new Scanner(System.in);
                if(input.hasNextDouble() == true){
                    money = input.nextDouble();
                    break;
                }else{
                    System.out.print("输入错误!请重新输入:");
                    
                }
            }
            if(money < 50){
                System.out.println("输入金额少于50元请重新输入:");
                continue;
            }else{
                cards.get(number).setMoney(cards.get(number).getMoney() + money);
                System.out.println("充值成功,当前话费余额为" + dataFormat(cards.get(number).getMoney()));
                break;
            }
        }
        
    }
    
    
    /**
     *使用嗖嗖
     * @param number
     */
    public static void userSoso(String number){
        //添加场景Map集合的键值对
        scenes.put(0, scene0);
        scenes.put(1, scene1);
        scenes.put(2, scene2);
        scenes.put(3, scene3);
        scenes.put(4, scene4);
        scenes.put(5, scene5);
        
        MobileCard card = cards.get(number);  //获取此卡对象
        ServicePackage pack = card.getSerPackage();  //获取此卡所属套餐
        Random random = new Random();
        int ranNum = 0;
        int temp = 0; //记录各场景中的实际消费数据
        do{
            ranNum = random.nextInt(6);
            Scene scene = scenes.get(ranNum); //获取该序号所有对应的场景
            switch(ranNum){
            case 0:
            case 1:
                //序号为0或1的通话场景
                //获取该卡所属套餐是否支持通话功能
                if(pack instanceof CallService){
                    //执行通话方法
                    System.out.println(scene.getDescription());
                    CallService callService = (CallService) pack;
                    try {
                        temp = callService.call(scene.getData(), card);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    //添加一条消费记录
                    addConsumInfo(number, new ConsumInfo(number, scene.getType(), temp));
                    break;
                }else{
                    //如果该卡套餐不支持通话功能,则重新生成随机数选择其他场景
                    continue;
                }
            case 2:
            case 3:
                //序号2或3发短信场景
                //获取该卡所属套餐是否支持短信
                if(pack instanceof SendService){
                    //执行短信方法
                    System.out.println(scene.getDescription());
                    SendService sendService = (SendService) pack;
                    try {
                        temp = sendService.send(scene.getData(), card);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    //添加一条消费记录
                    addConsumInfo(number, new ConsumInfo(number, scene.getType(), temp));
                    break;
                }else{
                    //如果该卡套餐不支持短信功能,则重新生成随机数选择其他场景
                    continue;
                }
            case 4:
            case 5:
                //获取该卡所属套餐是否支持上网
                if(pack instanceof NetService){
                    //执行上网方法
                    System.out.println(scene.getDescription());
                    NetService netService = (NetService) pack;
                    try {
                        temp = netService.netPlay(scene.getData(), card);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    //添加一条消费记录
                    addConsumInfo(number, new ConsumInfo(number, scene.getType(), temp));
                    break;
                }else{
                    //如果该卡套餐不支持上网功能,则重新生成随机数选择其他场景
                    continue;
                }
            }
            break;
        }while(true);
    }
    
    
    /**
     *资费说明
     */
    public static void showDescription(){
        FileReader fr = null;
        BufferedReader br = null;
        try {
            //创建一个FileReader对象
            fr = new FileReader("套餐资费说明.txt");
            //创建一个BufferedReader对象
            br = new BufferedReader(fr);
            //读取一行数据
            String line = null;
            while((line = br.readLine()) != null){
                System.out.println(line);
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                if(br != null){
                    br.close();
                }
                if(fr != null){
                    fr.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    
    
    /**
     *本月账单查询
     * @param number
     */
    public static void showAmountDetail(String number){
        MobileCard mobileCard = cards.get(number);
        System.out.println("您的卡号为:" + mobileCard.getCardNumber());
        System.out.println("当月账单如下:");
        System.out.println("套餐资费:" + dataFormat(mobileCard.getSerPackage().getPrice()) + "元"
                + "	合计消费:" + dataFormat(mobileCard.getConsumAmount()) + "元"
                + "	账户余额:" +  dataFormat(mobileCard.getMoney()) + "元");
    }
    
    
    /**
     * 套餐余量查询
     * @param searchNumber
     */
    public static void showRemainDetail(String searchNumber){
        MobileCard mobileCard = cards.get(searchNumber);
        int remainTalkTime;
        int remainSmsCount;
        int remainFlow;
        StringBuffer meg = new StringBuffer();
        meg.append("您的卡号是" + searchNumber + ",套餐内剩余:
");
        ServicePackage pack = mobileCard.getSerPackage();
        if(pack instanceof TalkPackage){
            //向下转型为话唠对象
            TalkPackage cardPack = (TalkPackage)pack;
            //话唠套餐,查询套餐内剩余的通话时长和短信数
            remainTalkTime = cardPack.getTalkTime() > mobileCard
                    .getRealTalkTime() ? cardPack.getTalkTime()
                    - mobileCard.getRealTalkTime() : 0;
            meg.append("通话时长:" + remainTalkTime + "分钟
");
            remainSmsCount = cardPack.getSmsCount() > mobileCard
                    .getRealSMSCount() ? cardPack.getSmsCount()
                    - mobileCard.getRealSMSCount() : 0;
                    meg.append("短信条数:" + remainSmsCount + "条");
        }else if(pack instanceof NetPackage){
            //向下转型为网虫对象
            NetPackage cardPack = (NetPackage)pack;
            //网虫套餐查询上网流量
            remainFlow = cardPack.getFlow() > mobileCard
                    .getRealFlow() ? cardPack.getFlow()
                            - mobileCard.getRealFlow() : 0;
            meg.append("上网流量:" + dataFormat(remainFlow * 1.0 / 1024) + "GB");
        }else if(pack instanceof SuperPackage){
            //向下转型为超人对象
            SuperPackage cardPack = (SuperPackage)pack;
            //超人套餐查询通话时长、上网流量、短信条数。
            remainTalkTime = cardPack.getTalkTime() > mobileCard
                    .getRealTalkTime() ? cardPack.getTalkTime()
                            - mobileCard.getRealTalkTime() : 0;
            meg.append("通话时长:" + remainTalkTime + "分钟
");
            remainFlow = cardPack.getFlow() > mobileCard
                    .getRealFlow() ? cardPack.getFlow()
                            - mobileCard.getRealFlow() : 0;
            meg.append("上网流量:" + dataFormat(remainFlow * 1.0 / 1024) + "GB");
            remainSmsCount = cardPack.getSmsCount() > mobileCard
                    .getRealSMSCount() ? cardPack.getSmsCount()
                    - mobileCard.getRealSMSCount() : 0;
            meg.append("短信条数:" + remainSmsCount + "条");
        }
        System.out.println(meg);
        
    }
    

    /**
     * 打印消费详单
     * @param number
     */
    public static void printAmountDetail(String number){
        Writer fileWriter = null;
        try {
            fileWriter = new FileWriter(number + "消费记录.txt");
            Set<String> numbers = consumInfos.keySet();
            Iterator<String> it = numbers.iterator();
            List<ConsumInfo> infos = new ArrayList<ConsumInfo>();
            infos = consumInfos.get(number);
            //存储指定卡的所有消费记录
            //现有消费列表中是否存在此卡号的消费记录,是:true 否:false
            boolean isExist = false;
            while(it.hasNext()){
                String numberKey = it.next();
                if(number.equals(numberKey)){
                    isExist = true;
                }/*else{   //如果
                    isExist = false;
                }*/
                
            }
            
            if(isExist){
                StringBuffer content = new StringBuffer("***********" + number + "消费记录************
");
                content.append("序号	类型	数据(通话(分钟)/上网(MB)/短信(条))
");
                for(int i = 0; i < infos.size(); i++){
                    ConsumInfo info = infos.get(i);
                    //System.out.println((i + 1) + ".	" + info.getType() + "	" + info.getConsumData() + "
");
                    content.append((i + 1) + ".	" + info.getType() + "	" + info.getConsumData() + "
");
                }
                fileWriter.write(content.toString());
                fileWriter.flush();
                System.out.println("消息记录打印完毕!");
            }else{
                System.out.println("对不起,不存在此号码的消费记录,不能够打印!");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * 套餐变更
     * @param number
     */
    public static void changingPack(String number){
        System.out.println("1.话唠套餐 2.网虫套餐 3.超人套餐 :请选择(序号):");
        int packNum = input.nextInt();
        switch(packNum){
        case 1:  //选择变更的套餐为话唠套餐
            if(cards.get(number).getSerPackage() instanceof TalkPackage){
                System.out.println("对不起,您已经是该套餐用户,无需换套餐!");
            }else{
                if(cards.get(number).getMoney() < cards.get(number).getSerPackage().getPrice()){//如果剩余费用不够支持新的套餐费用
                    System.out.println("对不起,您的的余额不足以支付新的套餐本月资费,请充值后再办理业务!");
                }else{
                    cards.get(number).setRealSMSCount(0);
                    cards.get(number).setRealTalkTime(0);
                    cards.get(number).setRealFlow(0);
                    cards.get(number).setSerPackage(Common.talkPackage);
                    System.out.println("套餐更换成功!" );
                    Common.talkPackage.showInfo();
    
                }
            }
            break;
        case 2: //选择变更的套餐为网虫套餐
            if(cards.get(number).getSerPackage() instanceof NetPackage){
                System.out.println("对不起,您已经是该套餐用户,无需换套餐!");
            }else{
                if(cards.get(number).getMoney() < cards.get(number).getSerPackage().getPrice()){//如果剩余费用不够支持新的套餐费用
                    System.out.println("对不起,您的的余额不足以支付新的套餐本月资费,请充值后再办理业务!");
                }else{
                    cards.get(number).setRealSMSCount(0);
                    cards.get(number).setRealTalkTime(0);
                    cards.get(number).setRealFlow(0);
                    cards.get(number).setSerPackage(Common.netPackage);
                    System.out.println("套餐更换成功!" );
                    Common.netPackage.showInfo();
    
                }
            }
            break;
        case 3://选择变更的套餐为超人套餐
            if(cards.get(number).getSerPackage() instanceof SuperPackage){
                System.out.println("对不起,您已经是该套餐用户,无需换套餐!");
            }else{
                if(cards.get(number).getMoney() < cards.get(number).getSerPackage().getPrice()){//如果剩余费用不够支持新的套餐费用
                    System.out.println("对不起,您的的余额不足以支付新的套餐本月资费,请充值后再办理业务!");
                }else{
                    cards.get(number).setRealSMSCount(0);
                    cards.get(number).setRealTalkTime(0);
                    cards.get(number).setRealFlow(0);
                    cards.get(number).setSerPackage(Common.superPackage);
                    System.out.println("套餐更换成功!" );
                    Common.superPackage.showInfo();
    
                }
            }
            break;
        }
    }
    
    
    /**
     * 办理退网
     * @param number
     */
    public static void delCard(String number){
        Set<String> numberKeys = cards.keySet();
        Iterator<String> it = numberKeys.iterator();
        while(it.hasNext()){
            String numberKey = it.next();
            if(numberKey.equals(number)){
                cards.remove(numberKey);
                //下面这这句话可能会报异常标记*
                System.out.println("卡号" + number + "办理退网成功
谢谢使用!");
            }else{
                System.out.println("办理退卡失败!");
            }
        }
    }
    
    /**
     * 根据卡号和密码验证该卡是否注册
     * @param number
     * @param passWord
     * @return boolean
     */
    public static boolean isExistCard(String number, String passWord){
        if(cards.size()!= 0){
            Set<String> numberKeys = cards.keySet();
            //System.out.println(numberKeys);
            Iterator<String> its = numberKeys.iterator(); 
            while(its.hasNext()){
                String numberKey = its.next();
                MobileCard mobileCard = cards.get(numberKey); //根据key取出对应的值
                //System.out.println("mobileCard.getPassWord():" + mobileCard.getPassWord() + "	 passWord:" + passWord);
                //System.out.println("numberKey:" + numberKey + "	 number:" + number);
                if(number.trim().equals(numberKey.trim()) && passWord.trim().equals(mobileCard.getPassWord().trim())){
                    System.out.println("该用户存在,且帐号密码都正确");
                    return true;
                }else if(number.trim().equals(numberKey.trim()) == true && passWord.trim().equals(mobileCard.getPassWord().trim()) == false){
                    System.out.println("该用户存在,但密码错误");
                    return false;
                }/*else if(number.trim().equals(numberKey.trim()) == false){ 这条语句如果不注释掉会阻碍循环
                    System.out.println("该用户不存在");
                    return false;
                    
                }*/
            }
            System.out.println("该用户不存在");
            return false;
        }else{
            System.out.println("cards集合为空,不存在用户!");
            return false;
        }
        /*System.out.println("其它情况");
        return false;*/
    }
    
    //根据卡号验证该卡号是否注册
    /**
     * 
     * @param number
     * @return boolean
     */
    public static boolean isExistCard(String number){
        if(cards.size()!= 0){
            Set<String> numberKeys = cards.keySet();
            Iterator<String> its = numberKeys.iterator(); 
            while(its.hasNext()){
                if(number.equals(its.next())){
                    //System.out.println("该用户已经注册!");
                    return true;
                }/*else{
                    System.out.println("该用户不存在!");  //需要将该语句写到循环外边,否则会影响遍历
                    return false;
                }*/
            }
            System.out.println("该用户不存在!");
            return false;
        }else{
            System.out.println("cards集合为空,不存在用户!");
            return false;
        }
    }
    
    
    /**
     * 生成随机卡号
     * @return 随机号
     */
    public static String createNumber(){
        Random random = new Random();
        //记录现有用户中是否存在此卡号用户  是:true  否:false
        boolean isExist = false;
        String number = "";
        int temp = 0;
        do{
            isExist = false;//标志位重置为false,用于控制外重循环
            //生成的随机数是8位,不能小于10000000,否则重新生成
            //回头重写这段代码,执行效率太低
            do{
                temp = random.nextInt(100000000);
            }while(temp < 10000000);
            //生成之前,前面加“139”
            number = "139" + temp;
            //和现有用户的卡号比较,不能是重复的
            if(cards != null){ //价格判断 否则 下方的一句会报空指针异常
                Set<String> cardNumbers = cards.keySet();
                for(String cardNumber : cardNumbers){
                    if(number.equals(cardNumber)){
                        isExist = true;
                        break;
                    }
                }
            }
            
            
        }while(isExist);
        return number;
    }
    
    /**
     * 生成指定个数的卡号列表 (回头尝试是否可以通过返回集合列表的方式显示)
     * @param count
     * @return String[]
     */
    public static String[] getNewNumbers(int count){
        String[] strs = new String[count];
        for (int i = 0; i < count; i++) {
            //strs[i] = new String();
            strs[i] = createNumber();  //通过随机生成给strs[i]赋值
        }
        return strs ;
    }
    
    /**
     * 添加指定卡号的消费记录
     * @param number
     * @param info
     */
    public static void addConsumInfo(String number, ConsumInfo info){
        if(consumInfos.containsKey(number)){
            consumInfos.get(number).add(info);
        }else{
            List<ConsumInfo> list = new ArrayList<ConsumInfo>();
            list.add(info);
            consumInfos.put(number, list);
        }
        
        //下边这种方法是错误的,原因在于consumInfos原本为空 it.hasNext()为false直接跳出了
        /*Set<String> numberKeys = consumInfos.keySet();
        System.out.println("调试,输出key键" + numberKeys);
        Iterator<String> it = numberKeys.iterator();
        while(it.hasNext()){//判断此卡是否有消费记录,如果有直接在集合consumInfos的值List<ConsumInfo>中添加数据,如果没有则新建一个List<ConsumInfo>集合,然后再添加键值对
            String numberKey = it.next();
            if(numberKey.equals(number)){
                consumInfos.get(numberKey).add(info);
                System.out.println("有这个卡的消费记录");
            }else{
                List<ConsumInfo> list = new ArrayList<ConsumInfo>();
                list.add(info);
                consumInfos.put(number, list);
                System.out.println("没有这个卡的消费记录");
            }
        }*/
    }
    
    //根据用户选择的套餐序号返回套餐对象
    /*public static ServicePackage createPack(int packId){
        ServicePackage sp = new SuperPackage();
        return sp;
    }*/
    
    /**
     * 客户服务端函数
     */
    public static void ask_Client_Method(){
        Scanner input = new Scanner(System.in);
        //定义服务器的地址,端口号,数据
        //创建DatagramSocket,实现数据发送和接收
        DatagramSocket socket;
        try {
            InetAddress address = InetAddress.getByName("localhost");
            int port = 8800;
            DatagramPacket packet; 
            DatagramPacket packet2;
            socket = new DatagramSocket();
            System.out.println("您好,美女小兰为您服务!");
            String str = "";
      while(!str.equals("886")) {
               System.out.print("用户说:");
               str = input.next();
               byte[] data = str.getBytes();
               //创建数据报
               packet = new DatagramPacket(data, data.length, address, port);
              
               //向服务器端发送数据报
               socket.send(packet);
               
               //接收服务器响应数据
               byte[] data2 = new byte[1024];
               packet2 = new DatagramPacket(data2, data2.length);
               socket.receive(packet2);
               String info = new String(data2, 0, packet2.getLength());
               System.out.println("客服说:"+info);
              
          }
          socket.close();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SocketException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
 
    }
    
    /**
     * 将double数据格式化输出
     * @param data
     * @return
     */
    public static String dataFormat(double data){
        DecimalFormat formatData = new DecimalFormat("#0.0");
        return formatData.format(data);
    }
    
    
}

业务类:

package cn.luoxue.search_The_mobile_lobby;

import java.util.Scanner;

/**
 * 业务类
 * @author 三文鱼的回流
 *
 */
public class SosoMgr {
    Scanner input = new Scanner(System.in);
    
    /**
     *实现主菜单 
     */
    public void mainMenu(){
        String number = "";  //切记不要放到循环里面 ,会重新初始化会报空指针异常
        boolean flag = true; //控制do-while循环
        
        do{
            
            //显示一级菜单
            showLevel1Menu();
            System.out.print("请选择:");
            String num = input.next();
            switch(num){
            case "1":
                System.out.println("执行使用《用户登录》功能");
                System.out.print("请输入您的手机号:");
                number = input.next();
                System.out.print("请输入您的密码:");
                String passWord = input.next();
                //通过手机号判断该用户是否存在
                //CardUtil.isExistCard(number);
                //通过手机号和密码判断该用户是否存在
                //CardUtil.isExistCard(number, passWord);
                if(CardUtil.isExistCard(number, passWord)){
                    cardMenu(number);
                }
                
                flag = true;
                break;
            case "2":
                System.out.println("执行使用《用户注册》功能");
                registCard();
                
                flag = true;
                break;
            case "3":
                System.out.println("执行使用《使用嗖嗖》功能");
                System.out.println("请输入手机卡号:");
                String soso_Number = input.next();
                if(CardUtil.isExistCard(soso_Number)){ //如果用户存在则执行Soso功能
                    CardUtil.userSoso(soso_Number);
                }
                
                flag = true;
                break;
            case "4":
                System.out.println("执行使用《话费充值》功能");
                System.out.println("请输入充值卡号:");
                String refill_Number = input.next();
                if(CardUtil.isExistCard(refill_Number)){ //如果用户存在则执行充值功能
                    CardUtil.chargeMoney(refill_Number);
                }
                
                flag = true;
                break;
            case "5":
                System.out.println("执行使用《资费说明》功能");
                CardUtil.showDescription();
                flag = true;
                break;
            case "6":
                System.out.println("执行使用《客户咨询》功能");
                CardUtil.ask_Client_Method();
                flag = true;
                break;
            case "7":
                System.out.println("执行使用《退出系统》功能");
                System.out.println("谢谢使用");
                flag = false; //退出do-while循环
                break;
            default:
                System.out.println("输入错误,请重来!");
                flag = true;
                break;
            }
        }while(flag);
    }
    
    
    /**
     *实现二级菜单
     * @param number
     */
    public void cardMenu(String number){
        //Scanner input = new Scanner(System.in);
        //MobileCard mobileCard = new MobileCard();
        //Common.mobileCard = CardUtil.cards.get(number);
    
        boolean flag = true; //控制do-while循环
        while(flag){
            //显示二级菜单
            showLevel2Menu();
            System.out.println("请选择(输入1~5选择功能,其它键返回上一级):");
            String num = input.next();
            switch(num){
            case "1":
                System.out.println("执行使用《本月账单查询》功能");
                //CardUtil.showAmountDetail(Common.mobileCard.getCardNumber());//为什么这样会报空指针异常
                CardUtil.showAmountDetail(number);
                flag = true;
                break;
            case "2":
                System.out.println("执行使用《套餐余量查询》功能");
                CardUtil.showRemainDetail(number);
                flag = true;
                break;
            case "3":
                System.out.println("执行使用《打印消费详情》功能");
                CardUtil.printAmountDetail(number);
                //调试用到的System.out.println(CardUtil.consumInfos.keySet());
                flag = true;
                break;
            case "4":
                System.out.println("执行使用《套餐变更》功能");
                CardUtil.changingPack(number);
                flag = true;
                break;
            case "5":
                System.out.println("执行使用《办理退网》功能");
                CardUtil.delCard(number);
                flag = true;
                break;
            default:
                flag = false;
                break;
            }
            if (flag) {
                System.out.print("输入0返回上一层,输入其他键返回首页:");
                String strNum = input.next();
                if (strNum.equals("0")) {
                    continue;
                } else {
                    flag = false;
                }
            }
        }
    }
    
    
    /**
     *显示一级菜单
     */
    public static void showLevel1Menu(){
        System.out.println("*****************欢迎使用嗖嗖移动业务大厅***************");
        System.out.println("1.用户登录   2.用户注册  3.使用嗖嗖  4.话费充值  5.资费说明   6.客户咨询  7.退出系统");
    }
    
    
    /**
     *显示二级菜单 
     */
    public void showLevel2Menu(){
        System.out.println("***********嗖嗖移动用户菜单***********");
        System.out.println("1.本月账单查询");
        System.out.println("2.套餐余量查询");
        System.out.println("3.打印消费详单");
        System.out.println("4.套餐变更");
        System.out.println("5办理退网");
    }

    
    /**
     *用户注册流程
     */
    public void registCard(){
        MobileCard mobileCard = new MobileCard();
        //Scanner input = new Scanner(System.in);
        System.out.println("************可选择的卡号************");
        //通过超级循环遍历输出卡号
        String[] cardNumbers = CardUtil.getNewNumbers(9);
        for (int i = 0; i < cardNumbers.length; i++) {
            System.out.print((i + 1) + "." + cardNumbers[i] + "	");
            if(2 == i || 5 == i || 8 == i) {
                System.out.println();
            }
        }
        System.out.print("请选择卡号:");
        while(true){  //此循环体内部的功能,保证了在使用input.nextInt的情况下,如果输入字母也不会报异常
            Scanner input = new Scanner(System.in);  //该语句不能放到while循环体外部,否则会造成死循环
            if(input.hasNextInt() == true){  //input.hasNextInt() == true 判断输入是否为int型
                int num = input.nextInt(); 
                if(0 < num && num < 10){
                    mobileCard.setCardNumber(cardNumbers[num - 1]);
                    break;
                }else{
                    System.out.print("输入错误!请输入(1~9)的数字:");
                    continue;
                }
            }else{
                System.out.print("输入错误!请输入(1~9)的整数:");
                continue;
            }
        }
        System.out.println("1.话唠套餐  2.网虫套餐  3.超人套餐 , 请选择套餐(输入序号):");
        boolean bol = true;
        while(bol){
            String packageNumStr = input.next();
            switch(packageNumStr){
                case "1":
                    mobileCard.setSerPackage(Common.talkPackage);
                    bol = false;
                    break;
                case "2":
                    mobileCard.setSerPackage(Common.netPackage);
                    bol = false;
                    break;
                case "3":
                    mobileCard.setSerPackage(Common.superPackage);
                    bol = false;
                    break;
                default:
                    System.out.println("输入错误,请重新选择:");
                    bol = true;
                    break;
            }
        }
        
        System.out.println("请输入姓名:");
        String userName =  input.next();
        mobileCard.setUserName(userName);
        System.out.println("请输入密码:");
        String passWord = input.next();
        mobileCard.setPassWord(passWord);
        System.out.println("请输入预存话费:");
        double money = 0.0;
        boolean flag = false;//控制循环以及控制if语句
        do{
            if(flag == true){
                System.out.println("您预存的话费金额不足以支付本月固定套餐资费("+ mobileCard.getSerPackage().getPrice() +"元),请重新充值:");
            }
            
            while(true){
                Scanner input = new Scanner(System.in);
                if(input.hasNextDouble() == true){
                    money = input.nextDouble();
                    break;
                }else{
                    System.out.println("输入错误!请重新输入");
                }
            }
            flag = (money < 58 && mobileCard.getSerPackage() == Common.talkPackage) || (money < 68 && mobileCard.getSerPackage() == Common.netPackage) || (money < 78 && mobileCard.getSerPackage() == Common.superPackage);
        }while(flag);
        mobileCard.setMoney(money);
        CardUtil.cards.put(mobileCard.getCardNumber(), mobileCard);
        //CardUtil.addCard(mobileCard); //注册新卡
        System.out.println("注册成功!卡号:" + mobileCard.getCardNumber() + ",用户名:" + mobileCard.getUserName() + ",当前余额为:" + mobileCard.getMoney() + "元");
        mobileCard.getSerPackage().showInfo();
        System.out.println("
");
    }
    public static void main(String[] args) {
        MobileCard mobileCard = new MobileCard("11588460776", "落雪", "123", Common.superPackage, 0, 100, 0, 0, 0);
        CardUtil.addCard(mobileCard);
        SosoMgr sosoMgr = new SosoMgr();
        sosoMgr.mainMenu();
    }
    
}

公共类等:

package cn.luoxue.search_The_mobile_lobby;

import cn.luoxue.entityclass.NetPackage;
import cn.luoxue.entityclass.SuperPackage;
import cn.luoxue.entityclass.TalkPackage;

/**
 * 公共类
 * @author 三文鱼的回流
 *
 */
public class Common {
        //实例化嗖嗖移动卡
        //static MobileCard mobileCard = new MobileCard();
        //实例化话唠套餐
        static TalkPackage talkPackage = new TalkPackage(58, 500, 30);
        //实例化网虫套餐
        static NetPackage netPackage = new NetPackage(68, 3 * 1024);
        //实例化超人套餐
        static SuperPackage superPackage = new SuperPackage(78, 200, 50, 1 * 1024);
}

嗖嗖移动卡类

package cn.luoxue.search_The_mobile_lobby;

import cn.luoxue.entityclass.ServicePackage;

/**
 * 嗖嗖移动卡类
 * @author Administrator
 *
 */
public class MobileCard {
    private String cardNumber;//卡号
    private String userName; //用户名
    private String passWord; //密码
    private ServicePackage serPackage; //所属套餐
    private double consumAmount; //当月消费金额
    private double money; //当月余额
    private int realTalkTime; //当月实际通话时长
    private int realSMSCount; //当月实际发送短信条数
    private int realFlow; //当月实际上网流量
    public MobileCard() {
        super();
    }
    
    public MobileCard(String cardNumber, String userName, String passWord,
            ServicePackage serPackage, double consumAmount, double money,
            int realTalkTime, int realSMSCount, int realFlow) {
        super();
        this.cardNumber = cardNumber;
        this.userName = userName;
        this.passWord = passWord;
        this.serPackage = serPackage;
        this.consumAmount = consumAmount;
        this.money = money;
        this.realTalkTime = realTalkTime;
        this.realSMSCount = realSMSCount;
        this.realFlow = realFlow;
    }

    public String getCardNumber() {
        return cardNumber;
    }

    public void setCardNumber(String cardNumber) {
        this.cardNumber = cardNumber;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public ServicePackage getSerPackage() {
        return serPackage;
    }

    public void setSerPackage(ServicePackage serPackage) {
        this.serPackage = serPackage;
    }

    public double getConsumAmount() {
        return consumAmount;
    }

    public void setConsumAmount(double consumAmount) {
        this.consumAmount = consumAmount;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    public int getRealTalkTime() {
        return realTalkTime;
    }

    public void setRealTalkTime(int realTalkTime) {
        this.realTalkTime = realTalkTime;
    }

    public int getRealSMSCount() {
        return realSMSCount;
    }

    public void setRealSMSCount(int realSMSCount) {
        this.realSMSCount = realSMSCount;
    }

    public int getRealFlow() {
        return realFlow;
    }

    public void setRealFlow(int realFlow) {
        this.realFlow = realFlow;
    }
    
    //显示嗖嗖移动卡的信息
    public void showMeg(){
        
    }
    
    
    
}

消费信息类:

package cn.luoxue.search_The_mobile_lobby;
/**
 * 消费信息类
 * @author 三文鱼的回流
 *
 */
public class ConsumInfo {
    private String cardNumber; //卡号
    private String type; //消费类型
    private int consumData; //消费数据
    
    public ConsumInfo() {
        super();
        // TODO Auto-generated constructor stub
    }

    public ConsumInfo(String cardNumber, String type, int consumData) {
        super();
        this.cardNumber = cardNumber;
        this.type = type;
        this.consumData = consumData;
    }

    public String getCardNumber() {
        return cardNumber;
    }

    public void setCardNumber(String cardNumber) {
        this.cardNumber = cardNumber;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public int getConsumData() {
        return consumData;
    }

    public void setConsumData(int consumData) {
        this.consumData = consumData;
    }
    
}

使用场景类

package cn.luoxue.search_The_mobile_lobby;
/**
 * 使用场景类
 * @author 三文鱼的回流
 *
 */
public class Scene {
    private String type; //场景类型
    private int data; //场景消费数据
    private String description; //场景描述
    public Scene() {
        super(); 
    }
    public Scene(String type, int data, String description) {
        super(); 
        this.type = type;
        this.data = data;
        this.description = description;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public int getData() {
        return data;
    }
    public void setData(int data) {
        this.data = data;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    
    
}
原文地址:https://www.cnblogs.com/ludengxiadeyingzi/p/7398326.html