写在前面:
每一个不曾起舞的日子,都是对生命的辜负。
希望看到这里的每一个人都能努力学习,不负韶华,成就更好的自己。
以下仅是个人学习过程中的一些想法与感悟,Java知识博大精深,作为初学者,个人能力有限,哪里写的不够清楚、明白,还请各位不吝指正,欢迎交流与讨论。如果有朋友因此了解了一些知识或对Java有了更深层次的理解,从而进行更进一步的学习,那么这篇文章的意义也就达到了。
目录
1.日志框架
1.1日志技术的概述
1.2日志技术体系结构
1.3Logback概述
1.4Logback快速入门
1.5Logback配置详解-输出位置、格式设置
1.6Logback配置详解-日志级别设置
2.阶段项目实战
2.1电影购票系统简介
2.2日志框架搭建、系统角色分析
2.3首页设计、登录、商家界面、用户界面实现
2.4商家-详情页设计、影片上架、退出
2.5商家-影片下架、影片修改
2.6用户-展示全部影片
2.7用户-购票功能
日志框架、阶段项目
1.日志框架
1.1日志技术的概述
日志技术具备的优势
可以将系统执行的信息选择性的记录到指定的位置(控制台、文件中、数据库中)。
可以随时以开关的形式控制是否记录日志,无需修改源代码。
日志技术的具体优势
|
输出语句 |
日志技术 |
输出位置 |
只能是控制台 |
可以将日志信息写入到文件或者数据库中 |
取消日志 |
需要修改代码,灵活性较差 |
不需要修改代码,灵活性较好 |
多线程 |
性能较差 |
性能较好 |
1.2日志技术体系结构
日志体系结构如下图所示。
日志规范:一些接口,提供给日志的实现框架设计的标准。
日志框架:者第三方公司已经做好的日志记录实现代码,后来者直接可以拿去使用。
1.3Logback概述
Logback是基于slf4j的日志规范实现的框架。
Logback主要分为三个技术模块:
logback-core:logback-core 模块为其他两个模块奠定了基础,必须有。
logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API。
logback-access:logback-access模块与 Tomcat 和 Jetty 等 Servlet 容器集成,以提供 HTTP 访问日志功能。
1.4Logback快速入门
需求:导入Logback日志技术到项目中,用于纪录系统的日志信息。
分析:
①:在项目下新建文件夹lib(lib代表依赖库,其中存放项目中可能会用到的jar包文件),导入Logback的相关jar包到该文件夹下,并添加到项目依赖库中去。
导入jar包具体步骤如下:
1):如下图所示,在要导入的工程中新建文件夹,起名为”lib”。
2):如下图所示,将提前下载好的jar包文件全部复制,粘贴到lib文件夹下。
如下图所示,在弹出的【复制】对话框中选择”重构”即可完成导入。
3):如下图所示,全部选中导入的jar包,右键选择”添加为库”。
在弹出的【Creat Library】对话框中选择”确定”即可完成将jar包添加到项目依赖库。
4):如下图所示,每个jar包前都有下拉菜单按钮,且能查看其中详细文件,代表jar包整合进工程成功。
②:将Logback的核心配置文件logback.xml(xml文件是项目的核心配置文件,其中进行相关功能的配置和控制)直接拷贝到src目录下(必须是src下)。
③:如下图所示,在代码中获取日志的对象。
④:使用日志对象LOGGER调用不同的方法在控制台/文件中输出不同的日志信息。
注:jar包是什么?
简单来说,jar包是对写好的类进行了打包。我们可以通过将jar包放到lib目录下来使用这些jar包中的类、属性和方法。
专业解释,JAR文件是Java Archive File-java档案文件的简称,是与平台无关的文件格式,基于zip文件格式将许多文件合成一个压缩文件.jar,区别是比zip多了一个 META-INF/MANIFEST.MF 文件,这个文件是在生成 JAR 文件的时候自动创建的。[1]
1.5Logback配置详解-输出位置、格式设置
Logback日志系统的特性都是通过核心配置文件logback.xml控制的。
Logback日志输出位置、格式设置:
通过logback.xml 中的标签可以设置输出位置和日志信息的详细格式。
通常可以设置2个日志输出位置:一个是控制台、一个是系统文件中。
输出到控制台的配置标志如下图所示。
输出到系统文件的配置标志如下图所示。
logback.xml文件示例代码如下:
System.out
%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %c [%thread] : %msg%n
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
utf-8
C:/code/itheima-data.log
C:/code/itheima-data2-%d{yyyy-MMdd}.log%i.gz
1MB
1.6Logback配置详解-日志级别设置
日志级别
级别程度依次是:TRACE< DEBUG< INFO
作用:用于控制系统中哪些日志级别是可以输出的,只输出级别不低于设定级别的日志信息。
ALL 和 OFF分别是打开全部日志信息及关闭全部日志信息。
日志级别具体在标签的level属性中设置。 可以包含零个或多个元素,标识这个输出位置将会被本日志级别控制,可按需求在此处配置关联打印位置(控制台或文件),否则不会打印。
2.阶段项目实战
2.1电影购票系统简介
电影购票系统技术选型分析:
(1)面向对象编程
系统包含了电影对象,商家对象,客户对象,需要用到继承、多态等语法知识。
(2)使用集合容器
系统需要提供不同的容器分别存储系统注册的用户,以及当前商家发布的电影信息。
(3)程序流程控制
需要结合分支、循环、跳转关键字等相关操作控制程序的业务逻辑。
(4)使用常见API
登录信息的内容比较,业务数据的分析、处理,日期时间的处理等。
2.2日志框架搭建、系统角色分析
日志框架搭建、系统角色分析具体步骤如下:
① 集成日志框架、用于后期记录日志信息。
② 定义一个电影类Movie类,Movie类包含:片名、主演、评分、时长、票价、余票。
③ 系统包含2个用户角色:客户、商家。存在大量相同属性信息。
④ 定义User类作为父类,属性:登录名称、密码、真实名称、性别、电话、账户金额。
⑤ 定义Business类代表商家角色,属性:店铺名称、地址。
⑥ 定义Customer类代表客户角色,属性:。
⑦ 定义集合List用户存放系统注册的用户对象信息。
⑧ 定义集合Map>存放商家和其排片信息。
⑨ 准备一些测试数据。
2.3首页设计、登录、商家界面、用户界面实现
首页、登录、商家界面、用户界面设计步骤如下:
① 首页需要包含登录,商家入驻,客户注册功能。
② 商家和客户可以共用一个登录功能。
③ 判断登录成功的用户的真实类型,根据用户类型完成对应的操作界面设计。
2.4商家-详情页设计、影片上架、退出
商家功能-展示详情、影片上架、退出步骤如下:
① 展示本商家的信息和其排片情况。
② 提供影片上架功能:就是创建一个影片对象,存入到商家的集合中去。
③ 退出,需要回到登录的首页。
易混淆点:
迭代器方法操作中间变量或原变量都不会改变原来变量的值;
非迭代器方法会改变原来变量的值。
详细理解为:
1、add(),remove(),set()方法操作中间变量会改变原变量的值。
2、iterator,stream()迭代器方法操作中间变量不会改变原变量的值,
3、需要注意,如果中间变量是基本数据类型,对这些基本数据类型的操作也不会改变原来变量的值。
如:原变量A为:Map A,中间变量为 List B = A.get();对B的操作会改变A的值,如果再下一层中间变量Integer C=B.get(),则对C的操作不会改变B和A。
2.5商家-影片下架、影片修改
商家功能-影片下架、影片修改步骤如下:
① 提供影片下架功能:其实就是从商家的集合中删除影片对象。
② 影片修改功能:拿到需要修改的影片对象,修改里面的数据。
2.6用户-展示全部影片
用户功能-展示全部影片信息步骤如下:
①遍历全部商家和其排片信息并展示出来
2.7用户-购票功能
用户功能-购票操作步骤如下:
① 用户可以选择需要购买票的商家和其电影信息。
② 可以选择购买的数量。
③ 购买成功后需要支付金额,并更新商家金额和客户金额。
示例代码如下:
用户类
public class User {
private String loginName; // 登录名
private String passWord; // 登陆密码
private String userName; // 用户姓名
private char sex; // 性别
private String phoneNumber; // 联系方式
private double money; // 账户余额
public User() {
}
public User(String loginName, String passWord, String userName, char sex, String phoneNumber, double money) {
this.loginName = loginName;
this.passWord = passWord;
this.userName = userName;
this.sex = sex;
this.phoneNumber = phoneNumber;
this.money = money;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
}
商家类
public class Business extends User{
private String shopName; // 店铺名
private String shopAddress; // 店铺地址
public String getShopName() {
return shopName;
}
public void setShopName(String shopName) {
this.shopName = shopName;
}
public String getShopAddress() {
return shopAddress;
}
public void setShopAddress(String shopAddress) {
this.shopAddress = shopAddress;
}
}
顾客类
public class Customer extends User{
}
电影类
public class Movie {
private String name; // 电影名称
private String actor; // 主演
private double score; // 评分
private double time; // 电影时长
private double price; // 票价
private int number; // 余票
private Date startTime; // 放映时间
public Movie() {
}
public Movie(String name, String actor, double time, double price, int number, Date startTime) { // 评分是用户评价的,不是创建对象时输入的,因此将score去掉
this.name = name;
this.actor = actor;
this.time = time;
this.price = price;
this.number = number;
this.startTime = startTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getActor() {
return actor;
}
public void setActor(String actor) {
this.actor = actor;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public double getTime() {
return time;
}
public void setTime(double time) {
this.time = time;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
}
测试类
public class MovieSystem {
// 创建logback日志对象,打印日志,只需要初始化一次,即可被所有程序使用
public static final Logger LOGGER = LoggerFactory.getLogger(MovieSystem.class);
// 定义一个静态扫描器,只需要初始化一次,即可被所有程序使用
public static final Scanner SYS_SC = new Scanner(System.in);
// 定义静态SimpleDateFormat对象,只需要初始化一次,即可被所有程序使用
public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 因当前登陆用户最多仅有一个,因此定义静态用户对象,代表当前已经登陆的对象,后续在使用过程中随时调用即可,无需再传User对象参数
public static User loginUser;
// 定义系统的数据容器用于存储用户数据
public static final List ALL_USERS = new ArrayList<>();
// 定义容器用于存储商家的排片信息
public static final Map> ALL_MOVIES = new HashMap<>();
// 准备一些测试数据
static {
Customer customer1 = new Customer();
customer1.setLoginName("abc123");
customer1.setPassWord("123456");
customer1.setUserName("张三");
customer1.setSex('男');
customer1.setMoney(10000);
customer1.setPhoneNumber("110110");
ALL_USERS.add(customer1);
Customer customer2 = new Customer();
customer2.setLoginName("xyz123");
customer2.setPassWord("123456");
customer2.setUserName("李四");
customer2.setSex('女');
customer2.setMoney(500);
customer2.setPhoneNumber("111111");
ALL_USERS.add(customer2);
Business business1 = new Business();
business1.setLoginName("wcCinema");
business1.setPassWord("123456");
business1.setUserName("王五");
business1.setMoney(0);
business1.setSex('男');
business1.setPhoneNumber("110110");
business1.setShopAddress("火星6号2B二层");
business1.setShopName("甜甜圈国际影城");
ALL_USERS.add(business1);
// 注意,商家一定需要加入到店铺排片信息中去
List movies = new ArrayList<>();
ALL_MOVIES.put(business1, movies);
Business business2 = new Business();
business2.setLoginName("dbCinema");
business2.setPassWord("123456");
business2.setUserName("赵六");
business2.setMoney(0);
business2.setSex('女');
business2.setPhoneNumber("110110");
business2.setShopAddress("火星8号8B八层");
business2.setShopName("巧克力国际影城");
ALL_USERS.add(business2);
// 注意,商家一定需要加入到店铺排片信息中去
List movies3 = new ArrayList<>();
// public Movie(String name, String actor, double time, double price, int number, Date startTime)
try {
Movie movie = new Movie("阿甘正传", "汤姆汉克斯", 120, 100, 10, sdf.parse("2022-05-16 16:30:00"));
Movie movie2 = new Movie("肖申克的救赎", "安迪", 120, 100, 10, sdf.parse("2022-05-16 16:30:00"));
movies3.add(movie);
movies3.add(movie2);
} catch (ParseException e) {
e.printStackTrace();
}
ALL_MOVIES.put(business2, movies3);
}
public static void main(String[] args) {
showMain();
}
/**
* create by: 全聚德在逃烤鸭、
* description: 首页展示
* create time: 2022/5/14 0014 10:38
*
* @param
* @return void
*/
private static void showMain() {
System.out.println("========wc电影首页=========");
while (true) {
System.out.println("请选择执行功能序号:1登陆\t2用户注册\t商家注册");
String command = SYS_SC.nextLine();
switch (command) {
case "1":
// 登陆
login();
break;
case "2":
// 用户注册
register();
break;
case "3":
// 商家注册
break;
default:
System.out.println("输入命令有误!请重新输入!");
}
}
}
/**
* create by: 全聚德在逃烤鸭、
* description: 用户注册
* create time: 2022/5/15 0015 21:04
*
* @param
* @return void
*/
private static void register() {
}
/**
* create by: 全聚德在逃烤鸭、
* description: 用户登陆
* create time: 2022/5/14 0014 10:46
*
* @param
* @return void
*/
private static void login() {
System.out.println("========用户登陆=========");
OUT:
while (true) {
System.out.println("请输入登陆名");
String loginName = SYS_SC.nextLine();
System.out.println("请输入登陆密码");
String userPassWord = SYS_SC.nextLine();
// 根据用户名查询用户对象
User user = getUserByLoginName(loginName);
if (user != null) {
// 查询密码是否正确
if (user.getPassWord().equals(userPassWord)) { // 密码输入正确
loginUser = user; // 将登陆成功的对象赋值代表当前登陆对象的给静态成员变量loginUser
LOGGER.info(loginUser.getLoginName() + "登陆成功!");
// 使用instanceof判断用户类型是用户还是商家
if (user instanceof Customer) { // 用户
showCustomerMain();
} else { // 否则为商家
showBusinessMain();
}
break;
} else { // 密码输入错误
System.out.println("密码错误,请重新登陆!");
}
} else {
System.out.println("用户名不存在!");
while (true) {
System.out.println("请选择执行功能序号:1重新登陆\t2退出到首页");
String command = SYS_SC.nextLine();
switch (command) {
case "1":
// 重新登陆
continue OUT;
case "2":
// 退出到首页
return;
default:
System.out.println("输入命令有误!请重新输入!");
}
}
}
}
}
/**
* create by: 全聚德在逃烤鸭、
* description: 商家页面
* create time: 2022/5/14 0014 11:14
*
* @param
* @return void
*/
private static void showBusinessMain() {
while (true) {
System.out.println("===========wc电影商家界面===================");
System.out.println(loginUser.getUserName() + (loginUser.getSex() == '男' ? "先生" : "女士" + "欢迎您进入系统"));
System.out.println("1、展示详情:");
System.out.println("2、上架电影:");
System.out.println("3、下架电影:");
System.out.println("4、修改电影:");
System.out.println("5、退出:");
System.out.println("请输入您要操作的命令:");
String command = SYS_SC.nextLine();
switch (command) {
case "1":
// 展示全部排片信息
showBusinessInfos();
break;
case "2":
// 上架电影信息
addMovie();
break;
case "3":
// 下架电影信息
deleteMovie();
break;
case "4":
// 修改电影信息
updateMovie();
break;
case "5":
System.out.println(loginUser.getUserName() + "退出成功!");
return;
default:
System.out.println("不存在该命令!!");
break;
}
}
}
/**
* create by: 全聚德在逃烤鸭、
* description: 修改上架影片
* create time: 2022/5/16 0016 9:19
*
* @param
* @return void
*/
private static void updateMovie() {
System.out.println("===========wc电影商家修改电影界面===================");
// 将User对象转换为真正的Business对象(当前对象实际上就是Business对象,不存在转换失败)
Business business = (Business) loginUser;
// 根据商家对象作为键提取其对应的值(当前上架的排片信息)
List movies = ALL_MOVIES.get(business);
if (movies.size() == 0) {
System.out.println("影院当前无放映信息");
return;
}
System.out.println("请输入要修改的电影名");
String movieName = SYS_SC.nextLine();
// 查询是否有movieName对应的影片
Movie movieByName = getMovieByNameStrictly(movieName);
if (movieByName != null) { // 查询到了符合条件的电影对象
while (true) {
try {
System.out.println("请您输入修改后的电影片名:");
String name = SYS_SC.nextLine();
System.out.println("请您输入修改后的主演:");
String actor = SYS_SC.nextLine();
System.out.println("请您输入修改后的电影时长:");
String timeStr = SYS_SC.nextLine();
double time = Double.parseDouble(timeStr);
System.out.println("请您输入修改后的票价:");
String priceStr = SYS_SC.nextLine();
double price = Double.parseDouble(priceStr);
System.out.println("请您输入修改后的票数:");
String numberStr = SYS_SC.nextLine();
int number = Integer.parseInt(numberStr);
System.out.println("请您输入修改后的影片放映时间:");
String startTimeStr = SYS_SC.nextLine();
Date startTime = sdf.parse(startTimeStr);
// 全部数据格式无误,将信息set修改到Movie对象中
movieByName.setName(name);
movieByName.setActor(actor);
movieByName.setTime(time);
movieByName.setPrice(price);
movieByName.setNumber(number);
movieByName.setStartTime(startTime);
System.out.println(name + "影片修改成功!");
showBusinessInfos();
return; // 排片信息修改完毕,退出该方法
} catch (NumberFormatException e) {
e.printStackTrace();
LOGGER.error("电影时长/票价/票数格式输入错误");
} catch (ParseException e) {
e.printStackTrace();
LOGGER.error("时间格式出现错误");
}
}
} else {
System.out.println("未查询到" + movieName + "相关的影片信息");
}
}
/**
* create by: 全聚德在逃烤鸭、
* description: 根据名称精确查询影片对象
* create time: 2022/5/16 0016 10:37
*
* @param movieName
* @return com.itheima.bean.Movie
*/
private static Movie getMovieByNameStrictly(String movieName) {
// 将User对象转换为真正的Business对象(当前对象实际上就是Business对象,不存在转换失败)
Business business = (Business) loginUser;
// 根据商家对象作为键提取其对应的值(当前上架的排片信息)
List movies = ALL_MOVIES.get(business);
// 遍历所有的电影对象,查询是否有该名称对应的电影对象
for (Movie movie : movies) {
if (movie.getName().equals(movieName)) { // 采用equals精确查询
return movie;
}
}
return null; // 遍历结束后没有查询到符合条件的影片对象,返回null
}
/**
* create by: 全聚德在逃烤鸭、
* description: 下架影片
* create time: 2022/5/16 0016 9:18
*
* @param
* @return void
*/
private static void deleteMovie() {
System.out.println("===========wc电影商家下架电影界面===================");
// 将User对象转换为真正的Business对象(当前对象实际上就是Business对象,不存在转换失败)
Business business = (Business) loginUser;
// 根据商家对象作为键提取其对应的值(当前上架的排片信息)
List movies = ALL_MOVIES.get(business);
if (movies.size() > 0) {
System.out.println("请输入要下架的电影名");
String movieName = SYS_SC.nextLine();
// 查询是否有movieName对应的影片
List moviesByName = getMovieByName(movieName);
if (moviesByName == null || moviesByName.size() == 0) { // 若集合为空或集合长度为0说明未查询到对应的电影对象
System.out.println("未查询到" + movieName + "相关的影片信息");
} else { // 否则说明查询到符合条件的电影对象
System.out.println("查询结果如下:");
showMovies(moviesByName);
while (true) {
System.out.print("确定要删除");
for (int i = 0; i < moviesByName.size(); i++) {
System.out.print(i == moviesByName.size() - 1 ? moviesByName.get(i).getName() : moviesByName.get(i).getName() + "、");
}
System.out.println("的排片信息?请输入是/否?");
String command = SYS_SC.nextLine();
switch (command) {
case "是":
// 将查询到的电影从当前上架的排片信息中删除
for (Movie movie : moviesByName) {
movies.remove(movie);
}
System.out.print("删除成功,已删除");
for (int i = 0; i < moviesByName.size(); i++) {
System.out.print(i == moviesByName.size() - 1 ? moviesByName.get(i).getName() : moviesByName.get(i).getName() + "、");
}
System.out.println("的排片信息!");
showBusinessInfos();
return;
case "否":
return;
default:
System.out.println("输入命令有误,请重新输入!");
}
}
}
} else {
System.out.println("影院当前无放映信息");
}
}
/**
* create by: 全聚德在逃烤鸭、
* description: 根据名称模糊查询影片对象
* create time: 2022/5/16 0016 9:32
*
* @param movieName
* @return java.util.List
*/
private static List getMovieByName(String movieName) {
// 将User对象转换为真正的Business对象(当前对象实际上就是Business对象,不存在转换失败)
Business business = (Business) loginUser;
// 根据商家对象作为键提取其对应的值(当前上架的排片信息)
List movies = ALL_MOVIES.get(business);
// 创建影片map集合,存储所有符合条件的影片
List moviesByName = new ArrayList<>();
// 遍历所有的电影对象,查询是否有该名称对应的电影对象
for (Movie movie : movies) {
if (movie.getName().contains(movieName)) { // 采用contains查询而不是equals,可以进行模糊查询,输入影片部分名称即可查询出影片,无需精确查询
moviesByName.add(movie); // 将查询到的影片信息加入到集合中
}
}
return moviesByName; // 遍历结束后将获取的影片集合返回
}
/**
* create by: 全聚德在逃烤鸭、
* description: 上架影片
* create time: 2022/5/15 0015 20:26
*
* @param
* @return void
*/
private static void addMovie() {
System.out.println("===========wc电影商家上架电影界面===================");
// 将User对象转换为真正的Business对象(当前对象实际上就是Business对象,不存在转换失败)
Business business = (Business) loginUser;
// 根据商家对象作为键提取其对应的值(当前上架的排片信息)
List movies = ALL_MOVIES.get(business);
while (true) {
try {
System.out.println("请您输入新片名:");
String name = SYS_SC.nextLine();
System.out.println("请您输入主演:");
String actor = SYS_SC.nextLine();
System.out.println("请您输入电影时长:");
String timeStr = SYS_SC.nextLine();
double time = Double.parseDouble(timeStr);
System.out.println("请您输入票价:");
String priceStr = SYS_SC.nextLine();
double price = Double.parseDouble(priceStr);
System.out.println("请您输入票数:");
String numberStr = SYS_SC.nextLine();
int number = Integer.parseInt(numberStr);
System.out.println("请您输入影片放映时间:");
String startTimeStr = SYS_SC.nextLine();
Date startTime = sdf.parse(startTimeStr);
// 全部数据格式无误,将信息封装成Movie对象,加入到该商家的排片List集合中
Movie movie = new Movie(name, actor, time, price, number, startTime);
movies.add(movie); // 引用类型,直接通过地址改变根数据,无需再将更新后的List集合更新到该商家对应的排片信息的map集合中
System.out.println(name + "影片添加成功!");
showBusinessInfos();
return; // 排片信息添加完毕,退出该方法
} catch (NumberFormatException e) {
e.printStackTrace();
LOGGER.error("电影时长/票价/票数格式输入错误");
} catch (ParseException e) {
e.printStackTrace();
LOGGER.error("时间格式出现错误");
}
}
}
/**
* create by: 全聚德在逃烤鸭、
* description: 展示当前登陆商家的详细信息
* create time: 2022/5/15 0015 19:55
*
* @param
* @return void
*/
private static void showBusinessInfos() {
System.out.println("===========wc电影商家详情界面===================");
// 将User对象转换为真正的Business对象(当前对象实际上就是Business对象,不存在转换失败)
Business business = (Business) loginUser;
// 展示商家信息
System.out.println(business.getShopName() + "\t\t电话:" + business.getPhoneNumber() + "\t\t地址:" + business.getShopAddress()
+ "\t\t余额:" + business.getMoney());
// 根据商家对象作为键提取其对应的值(当前上架的排片信息)
List movies = ALL_MOVIES.get(business);
if (movies.size() > 0) {
// 展示排片信息
showMovies(movies);
} else {
System.out.println("影院当前无放映信息");
}
}
/**
* create by: 全聚德在逃烤鸭、
* description: 展示集合中的电影详细信息
* create time: 2022/5/16 0016 9:38
*
* @param movies
* @return void
*/
private static void showMovies(List movies) {
System.out.println("片名\t\t主演\t\t时长\t\t评分\t\t放映时间\t\t票价\t\t余票数量");
for (Movie movie : movies) {
System.out.println(movie.getName() + "\t\t" + movie.getActor() + "\t\t" + movie.getTime() + "\t\t" + movie.getScore() + "\t\t"
+ sdf.format(movie.getStartTime()) + "\t\t" // 将影片放映时间格式化为提前设定好的格式
+ movie.getPrice() + "\t\t" + movie.getNumber());
}
}
/**
* create by: 全聚德在逃烤鸭、
* description: 普通用户页面
* create time: 2022/5/14 0014 11:14
*
* @param
* @return void
*/
private static void showCustomerMain() {
while (true) {
System.out.println("============wc电影客户界面===================");
System.out.println(loginUser.getUserName() + (loginUser.getSex() == '男' ? "先生" : "女士" + "欢迎您进入系统" +
"\t余额:" + loginUser.getMoney()));
System.out.println("请您选择要操作的功能:");
System.out.println("1、展示全部影片信息功能:");
System.out.println("2、根据电影名称查询电影信息:");
System.out.println("3、评分功能:");
System.out.println("4、购票功能:");
System.out.println("5、退出系统:");
System.out.println("请输入您要操作的命令:");
String command = SYS_SC.nextLine();
switch (command) {
case "1":
// 展示全部排片信息
showAllMovies();
break;
case "2":
break;
case "3":
// 评分功能
// scoreMovie();
// showAllMovies();
break;
case "4":
// 购票功能
buyMovie();
break;
case "5":
return;
default:
System.out.println("不存在该命令!!");
}
}
}
/**
* create by: 全聚德在逃烤鸭、
* description: 用户购票
* create time: 2022/5/16 0016 11:16
*
* @param
* @return void
*/
private static void buyMovie() {
System.out.println("============用户购票界面===================");
System.out.println("请输入购票门店名称:");
String shopName = SYS_SC.nextLine();
// 查询是否存在该商家
Business business = getBusinessByName(shopName);
if (business != null) {
// 查询此商家全部排片信息
List movies = ALL_MOVIES.get(business);
if (movies == null || movies.size() == 0) {
System.out.println("该商家尚未上架任何电影");
} else {
System.out.println("请输入购票电影名称:");
String movieName = SYS_SC.nextLine();
// 从当前上架上架的电影集合中查询是否存在符合条件的电影对象
Movie movie = getBusinessMovieByName(movies, movieName);
// 判断是否有符合条件的电影
if (movie != null) { // 存在
// 开始购买
while (true) {
try {
System.out.println("请输入购买数目:");
String numberStr = SYS_SC.nextLine();
int number = Integer.parseInt(numberStr);
// 判断该电影余票是否足够
if (movie.getNumber() >= number) {
// double money = movie.getPrice() * number; // 当前购票总费用
// double类型直接计算可能会出现精度丢失,使用BigDecimal.valueOf方法转换,再用multiply方法计算,最后在用doubleValue方法转换回double类型
double money = BigDecimal.valueOf(movie.getPrice()).multiply(BigDecimal.valueOf(number)).doubleValue(); // 当前购票总费用
if (loginUser.getMoney() >= money) {
// 更新电影票剩余数目
int ticketNumber = movie.getNumber() - number;
movie.setNumber(ticketNumber);
// 更新用户余额
double customerMoney = loginUser.getMoney() - money;
loginUser.setMoney(customerMoney);
// 更新商家余额
double businessMoney = business.getMoney() + money;
business.setMoney(businessMoney);
System.out.println(number + "张" + movieName + "电影票购买成功!,总金额为" + money + "元,当前账户余额" + loginUser.getMoney() + "元");
} else {
System.out.println("余额不足,无法购买!");
}
} else {
System.out.println(movieName + "余票不足,无法购买");
}
return;
} catch (Exception e) {
e.printStackTrace();
System.out.println("数据格式有误,请重新输入!");
LOGGER.error("数据格式有误");
}
}
} else { // 不存在
System.out.println("未查询到" + movieName + "相关的影片信息");
}
}
} else {
System.out.println("该商家不存在");
}
}
/**
* create by: 全聚德在逃烤鸭、
* description: 从当前上架上架的电影集合中查询是否存在符合条件的电影对象
* create time: 2022/5/16 0016 14:22
*
* @param movies 该商家当前上架的影片列表
* @param movieName
* @return com.itheima.bean.Movie
*/
private static Movie getBusinessMovieByName(List movies, String movieName) {
for (Movie movie : movies) {
if (movie.getName().equals(movieName)) {
return movie;
}
}
return null;
}
/**
* create by: 全聚德在逃烤鸭、
* description: 根据名称查询商家对象
* create time: 2022/5/16 0016 11:22
*
* @param shopName
* @return void
*/
private static Business getBusinessByName(String shopName) {
// ALL_MOVIES.forEach((business, movies) -> {
// if (business.getShopName().equals(shopName)) {
// return business; // ALL_MOVIES中每个值都是business = {m1, m2, m3, ... }的键值对形式,没有独立的Business对象,不能直接返回,需要取出键集合,再返回
// }
// });
Set businesses = ALL_MOVIES.keySet();
// 遍历businesses集合,查询是否存在某一商家,店铺名称与输入的名称相同
for (Business business : businesses) {
if (business.getShopName().equals(shopName)) {
return business; // 若存在,则将该商家对象返回
}
}
return null; // 若遍历结束后仍未查询到,说明不存在,返回null
}
/**
* create by: 全聚德在逃烤鸭、
* description: 展示全部商家及其排片信息
* create time: 2022/5/16 0016 11:05
*
* @param
* @return void
*/
private static void showAllMovies() {
System.out.println("============用户查询全部商家及其排片信息界面===================");
// 增强for循环仅支持Collection集合使用,map集合使用forEach循环
ALL_MOVIES.forEach((business, movies) -> {
System.out.println("影院名称:" + business.getShopName() + "\t\t电话:" + business.getPhoneNumber() + "\t\t地址:" + business.getShopAddress());
showMovies(movies);
});
}
/**
* create by: 全聚德在逃烤鸭、
* description: 根据用户名查询用户对象
* create time: 2022/5/14 0014 10:53
*
* @param loginName
* @return com.itheima.bean.User
*/
private static User getUserByLoginName(String loginName) {
// 遍历ALL_USERS集合,查询是否存在某一用户,用户名与输入的登录名相同
for (User user : ALL_USERS) {
if (user.getLoginName().equals(loginName)) {
return user; // 若存在,则将该User对象返回
}
}
return null; // 若遍历结束后仍未查询到,说明不存在,返回null
}
}
参考文献
[1]Azoner.jar包的概念及作用[J/OL].https://blog.csdn.net/Azoner/article/details/123954904,2022-04-04/2022-05-12
写在最后:
感谢读完!
纵然缓慢,驰而不息!加油!