【案例6-1】 库存管理系统
【案例介绍】
1.任务描述
像商城和超市这样的地方,都需要有自己的库房,并且库房商品的库存变化有专人记录,这样才能保证商城和超市正常运转。
本例要求编写一个程序,模拟库存管理系统。该系统主要包括系统首页、商品入库、商品显示和删除商品功能。每个功能的具体要求如下:
(1) 系统的首页:用于显示系统所有的操作,并且可以选择使用某一个功能。
(2) 商品入库功能:首先提示是否要录入商品,根据用户输入的信息判断是否需要录入商品。如果需要录入商品,则需要用户输入商品的名称、颜色、价格和数量等信息。录入完成后,提示商品录入成功并打印所有商品。如果不需要录入商品,则返回系统首页。
(3) 商品显示功能:用户选择商品显示功能后,在控制台打印仓库所有商品信息。
(4) 删除商品功能:用户选择删除商品功能后,根据用户输入的商品编号删除商品,并在控制台打印删除后的所有商品。
本案例要求使用Collection集合存储自定义的对象,并用迭代器、增强for循环遍历集合。
2.运行结果
商品首页运行结果如图6-1所示。
商品入库运行结果如图6-2所示:
商品显示运行结果如图6-3所示。
商品出库运行结果如图6-4所示:
图6-4 商品出库运行结果图
【案例任务】
-
学会分析“库存管理系统”任务的实现思路。
-
根据思路独立完成“库存管理系统”任务的源代码编写、编译及运行。
-
掌握Collection以及List集合常用方法的使用。
-
掌握迭代器,增强for循环的使用。
【案例思路】
(1)定义仓库产品类,自定义对象定义属性。
(2)在类中定义集合,将要存储的自定义对象作为泛型。
(3)主方法中为集合添加初始化的数据,采用无线循环的方式显示菜单栏。用if…else语句判断用户索要进行的操作,用户可以键盘输入1、2、3来选择对应的操作。如果输入1可以进行商品入库,输入2可以显示库房内所有商品,输入3可以删除进行商品出库,如果不是1、2、3则提示用户操作失败。
(4) 定义商品入库的方法,选择后首先提示用户是否录入商品。输入“no”不录入商品。直接退出并显示所有商品。输入其他任何数据开始录入商品并提示键盘输入什么。录入完毕后退出并显示所有商品。
(5) 定义显示仓库所有商品的方法,用Iterator迭代器的方法循环遍历集合打印,实现商品显示。
(6) 定义商品出库的方法,用集合删除的方法移除要删除的商品。
【案例实现】
其中实体类属性如文件6-1所示。
文件6-1 Phone.java
public class Phone {
private String name;
private String color;
private double price;
private int num;
}
以上代码是自定义对象实体类所包括的属性,我们在用时需要重写getter、setter以及构造方法。
库存管理系统的实现代码,如文件6-2所示。
文件6-2 example1.java
package com.itheima;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
public class example1 {
static Collection<Phone> c = new ArrayList();
public static void main(String[] args) {
c.add(new Phone("小米9", "玫瑰金",3999.00,15));
c.add(new Phone("小米9", "幻彩紫", 3699, 28));
c.add(new Phone("华为P30", "白金色", 5699, 2));
c.add(new Phone("华为P30", "绚彩白", 5999, 18));
c.add(new Phone("VIVO PLus9", "幻彩紫", 2699, 28));
c.add(new Phone("魅族 16th", "紫金黑", 5229, 10));
c.add(new Phone("苹果 11", "土豪金", 8999, 51));
while(true) {
System.out.println("欢迎使用库房管理系统,请选择要进行的操作");
System.out.println("1. 商品入库");
System.out.println("2. 商品显示");
System.out.println("3. 删除商品");
Scanner sc = new Scanner(System.in);
int s = sc.nextInt();
if(s == 1) {
addwarehouse();
System.out.println("商品入库成功,入库后仓库商品如下:");
warehouse();
}else if(s==2) {
warehouse();
}else if(s ==3) {
System.out.println("请输入你要删除的商品编号:");
int index=sc.nextInt();
delwarehouse(index);
System.out.println("商品出库成功,出库后仓库商品如下:");
warehouse();
}else {
System.out.println("操作失败!!!");
}
}
}
private static void addwarehouse() {
while(true) {
System.out.println("您是否录入商品?");
Scanner w = new Scanner(System.in);
String s=w.next();
if(!s.equals("no")) {
Scanner sc1 = new Scanner(System.in);
System.out.println("请输入商品的名称:");
String name=sc1.next();
System.out.println("请输入商品的颜色:");
String color=sc1.next();
System.out.println("请输入商品的价格:");
int p=sc1.nextInt();
System.out.println("请输入商品的数量:");
int n=sc1.nextInt();
c.add(new Phone(name,color,p,n));
break;
}else {
break;
}
}
}
private static void warehouse() {
//获取迭代器
Iterator it = c.iterator();
while(it.hasNext()) {
Phone s = (Phone)it.next(); //向下转型
System.out.println(s.getName()+ "..." + s.getColor() +
"..." + s.getPrice()+ "..." + s.getNum());
}
}
private static void delwarehouse(int index) {
c.remove(index);
}
}
在文件6-2中,第9行定义了一个集合c,泛型是我们的自定义对象Phone。同时定义为静态的。从而实现的代码的复用,减少了代码的冗余。第10~17
行代码是为我们定义的集合添加初始化的数据。
第18~41
行代码采用无线循环的方式显示菜单栏。用if…else语句判断用户索要进行的操作,用户可以键盘输入1、2、3来选择对应的操作。如果输入1可以进行商品入库,调用addwarehouse()方法实现添加商品入库,并且调用warehouse()方法实现入库后商品的显示。输入2可以显示库房内所有商品,调用warehouse()方法即实现商品的显示。输入3可以删除进行商品出库,调用delwarehouse(index)方法实现删除商品,并调用warehouse()方法即实现商品删除后的显示。用如果不是1、2、3则提示用户操作失败。
第42~64
代码定义商品入库的方法,选择后首先提示用户是否录入商品。输入“no”不录入商品。直接退出并显示所有商品。输入其他任何数据开始录入商品并提示键盘输入什么。录入完毕后退出并显示所有商品。
第67~74
行代码定义显示仓库所有商品的方法,用Iterator迭代器的方法循环遍历集合打印,实现商品显示。第76~78行代码定义商品出库的方法,用集合删除的方法移除要删除的商品。其中remove()方法是集合移除数据提供的方法。
【案例6-2】 学生管理系统
【案例介绍】
1.任务描述
在一所学校中,对学生人员流动的管理是很麻烦的,本案例要求编写一个学生管理系统,实现对学生信息的添加、删除、修改和查询功能。每个功能的具体要求如下:
(1) 系统的首页:用于显示系统所有的操作,并根据用户在控制台的输入选择需要使用的功能。
(2) 查询功能:用户选择该功能后,在控制台打印所有学生的信息。
(3) 添加功能:用户选择该功能后,要求用户在控制台输入学生学号、姓名、年龄和居住地的基本信息。在输入学号时,判断学号是否被占用,如果被占用则添加失败,并给出相应提示;反之则提示添加成功。
(4) 删除功能:用户选择该功能后,提示用户在控制台输入需要删除学生的学号,如果用户输入的学号存在则提示删除成功,反之则提示删除失败。
(5) 修改功能:用户选择该功能后,提示用户在控制台输入需要修改的学生学号、姓名、年龄和居住地学生信息,并使用输入的学生学号判断是否有此人,如果有则修改原有的学生信息,反正则提示需要修改的学生信息不存在。
(6) 退出功能:用户选择该功能后,程序正常关闭。
本案例要求使用List集合存储自定义的对象,使用List集合的中常用方法实现相关的操作。
2.运行结果
学生管理系统首页运行结果如图6-1所示。
学生管理系统查看所有学生运行结果如图6-2所示。
学生管理系统添加学生信息运行结果如图6-3所示:
学生管理系统修改学生信息结果如图6-4所示:
学生管理系统删除学生结果如图6-5所示。
【案例任务】
-
学会分析“学生管理系统”任务的实现思路。
-
根据思路独立完成“学生管理系统”任务的源代码编写、编译及运行。
-
掌握List集合常用方法的使用。
-
掌握循环遍历操作集合的使用。
【案例思路】
(1)定义学生类,自定义对象属性。
(2)学生管理系统的主界面的代码编写,创建集合对象,用于存储学生数据,打印学生管理系统主界面的相关功能,创建键盘输入功能,用switch语句实现选择的功能。最后为了实现多次操作并且手动退出系统。用while(true)循环实现.
(3) 学生管理系统查询所有学生信息的代码编写,首先判断集合中是否有数据,如果没有数据就给出提示,并让该方法不在继续往下执行。如果有数据。遍历集合输出打印数据。
(4) 学生管理系统添加学生信息的代码编写,首先输入学生学号,判断学号有没有被人占用,如果被占用重新输入学号,没有被占用继续录入学生姓名、年龄。家庭住址等信息。创建学生对象,将录入的数据存入对象。最后将学生对象添加入集合,添加学生信息成功。
(5) 学生管理系统删除学生信息的代码编写,键盘录入一个学号,到集合中去查找,看是否有学生使用该学号,如果有就删除该学生信息。如果没有学生使用该学号,返回主界面。
(6)学生管理系统修改学生信息的代码编写。键盘录入一个学号,到集合中去查找,看是否有学生使用该学号,如果过有就修改学生信息。反之返回主界面。
【案例实现】
学生实体类属性如文件6-1所示。
文件6-1 Student.java
public class Student {
//学号
private String id;
//姓名
private String name;
//年龄
private String age;
//居住地
private String address;
}
以上代码是我们自定义对象实体类所包括的属性,我们在用时需要重写get()、set()以及构造方法。
模拟学生管理系统的代码实现,如文件6-2所示。
文件6-2 example2.java
package com.itheima;
import java.util.ArrayList;
import java.util.Scanner;
public class example2 {
public static void main(String[] args) {
//创建集合对象,用于存储学生数据
ArrayList<Student> array = new ArrayList<Student>();
//为了让程序能够回到这里来,我们使用循环
while (true) {
//这是学生管理系统的主界面
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("请输入你的选择:");
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
String choiceString = sc.nextLine();
//用switch语句实现选择
switch (choiceString) {
case "1":
//查看所有学生
findAllStudent(array);
break;
case "2":
//添加学生
addStudent(array);
break;
case "3":
//删除学生
deleteStudent(array);
break;
case "4":
//修改学生
updateStudent(array);
break;
case "5":
//退出
//System.out.println("谢谢你的使用");
//break;
default:
System.out.println("谢谢你的使用");
System.exit(0); //JVM退出
break;
}
}
}
//查看所有学生
public static void findAllStudent(ArrayList<Student> array) {
//首先来判断集合中是否有数据,如果没有数据,就给出提示,并让该方法不继续往
下执行
if (array.size() == 0) {
System.out.println("不好意思,目前没有学生信息可供查询,请回去重新选择你
的操作");
return;
}
//\t 其实就是一个tab键的位置
System.out.println("学号\t姓名\t年龄\t居住地");
for (int x = 0; x < array.size(); x++) {
Student s = array.get(x);
System.out.println(s.getId() + "\t" + s.getName() + "\t"
+ s.getAge() + "\t" + s.getAddress());
}
}
//添加学生
public static void addStudent(ArrayList<Student> array) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
//为了让id能够被访问到,我们就把id定义在了循环的外面
String id;
//为了让代码能够回到这里,用循环
while (true) {
System.out.println("请输入学生学号:");
//String id = sc.nextLine();
id = sc.nextLine();
//判断学号有没有被人占用
//定义标记
boolean flag = false;
//遍历集合,得到每一个学生
for (int x = 0; x < array.size(); x++) {
Student s = array.get(x);
//获取该学生的学号,和键盘录入的学号进行比较
if (s.getId().equals(id)) {
flag = true; //说明学号被占用了
break;
}
}
if (flag) {
System.out.println("你输入的学号已经被占用,请重新输入");
} else {
break; //结束循环
}
}
System.out.println("请输入学生姓名:");
String name = sc.nextLine();
System.out.println("请输入学生年龄:");
String age = sc.nextLine();
System.out.println("请输入学生居住地:");
String address = sc.nextLine();
//创建学生对象
Student s = new Student();
s.setId(id);
s.setName(name);
s.setAge(age);
s.setAddress(address);
//把学生对象作为元素添加到集合
array.add(s);
//给出提示
System.out.println("添加学生成功");
}
//删除学生
public static void deleteStudent(ArrayList<Student> array) {
//删除学生的思路:键盘录入一个学号,到集合中去查找,看是否有学生使用的是该
学号,如果有就删除该学生
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入你要删除的学生的学号:");
String id = sc.nextLine();
//我们必须给出学号不存在的时候的提示
//定义一个索引
int index = -1;
//遍历集合
for (int x = 0; x < array.size(); x++) {
//获取到每一个学生对象
Student s = array.get(x);
//拿这个学生对象的学号和键盘录入的学号进行比较
if (s.getId().equals(id)) {
index = x;
break;
}
}
if (index == -1) {
System.out.println("不好意思,你要删除的学号对应的学生信息不存在,请回去
重新你的选择");
} else {
array.remove(index);
System.out.println("删除学生成功");
}
}
//修改学生
public static void updateStudent(ArrayList<Student> array) {
//修改学生的思路:键盘录入一个学号,到集合中去查找,看是否有学生使用的是该
学号,如果有就修改该学生
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入你要修改的学生的学号:");
String id = sc.nextLine();
//定义一个索引
int index = -1;
//遍历集合
for (int x = 0; x < array.size(); x++) {
//获取每一个学生对象
Student s = array.get(x);
//拿学生对象的学号和键盘录入的学号进行比较
if (s.getId().equals(id)) {
index = x;
break;
}
}
if (index == -1) {
System.out.println("不好意思,你要修改的学号对应的学生信息不存在,请回去
重新你的选择");
} else {
System.out.println("请输入学生新姓名:");
String name = sc.nextLine();
System.out.println("请输入学生新年龄:");
String age = sc.nextLine();
System.out.println("请输入学生新居住地:");
String address = sc.nextLine();
//创建学生对象
Student s = new Student();
s.setId(id);
s.setName(name);
s.setAge(age);
s.setAddress(address);
//修改集合中的学生对象
array.set(index, s);
//给出提示
System.out.println("修改学生成功");
}
}
}
在文件6-2中,第8行定义一个集合用于存储学生数据。其中该集合的泛型为Student。第10行代码定义一个while(true)循环使程序能够回到学生管理系统的主界面,第12~18
行用于显示主界面的菜单信息。
第20~21行代码定义键盘录入对象,用于选择我们要实现的功能。第23~48
行代码定义switch语句实现选择。case对应相应的功能。调用相应的程序代码 ,其中System.exit(0)表示JVM退出。
第52~68
行,定义一个实现学生信息查询方法。其中第55~59
行,首先用if判断集合中是否有数据,如果没有数据,就给出提示,并让该方法不继续往下执行。如果有数据,执行第62~66行遍历集合。并输出打印结果。
第70~114
行,定义一个实现添加学生信息的方法,其中第73行,定义一个id表示输入的学生的学号, 为了让id能够被访问到,我们就把id定义在了循环的外面。第76行,用while循环保证多次输入学号,直到输入的学号不重复。
第84~85
行代码表示循环遍历集合,获取每一个学生。第87行代码用if判断学号是否被占用。第116~142,行,定义一个删除学生信息的方法。第145~186
行,定义一个实现修改学生信息的方法。
【案例5-3】 模拟用户注册
【案例介绍】
1.任务描述
互联网为人们提供了巨大的便利,如微信带给人们的视频资源、淘宝带给人们便利的购物等,但这些APP都需要有一个账户才可以登录,而账户需要注册可以获取。
本例要求编写一个程序,模拟用户注册。用户输入用户名、密码、确认密码、生日(格式为yyyy–mm—dd为正确)、手机号(手机号长度为11位,并且以13、15、17、18为开头的手机号为正确)、邮箱(包含符号“@”为正确)信息之后,判断信息正确后,验证用户是否重复,重复则给出相应提示,如果不重复则注册成功。案例要求使用HashSet集合实现。
2.运行结果
任务运行结果如图6-1所示:
【案例任务】
-
学会分析“模拟微信用户注册”任务的实现思路。
-
根据思路独立完成“模拟微信用户注册”任务的源代码编写、编译及运行。
-
掌握HashSet集合常用方法的使用及存储数据的流程。
【案例思路】
(1) 为了便于存储用户的信息。需要创建一个用户类,在类中重写其中的HashCode()方法,令其返回用户的额哈希值,再重写equals()方法,来比较对象的用户属性是否相等。
(2) 创建一个用户注册类来模拟用户注册信息,该类中可以用HashSet集合创建一个数据列表,然后向列表中添加两条初始用户信息。
(3) 从控制台获取用户填写信息,通过Scanner类的nextline()方法实现,获取后,需要将获取的数据进行校验。
(4) 单独创建一个校验类,在该类中实现校验用户输入信息的方法。校验结束后,如果效验结果错误就直接返回错误信息,这里可以分别声明一个校验结果的变量和一个校验状态的变量。校验结果变量用于存储提示信息,校验状态变量用于存储结果的判断标识。
(5) 当用户输入的信息不满足规定的格式时,需要修改变量的状态并且存储错误信息。
(6) 判断校验状态,如果所有信息都通过校验,则将用户信息创建为用户对象,通过将对象添加到用户列表返回结果来判断用户是否重复,并记录下返回结果信息。
【案例实现】
(1)创建用户类,并重写其HashCode()和equals()方法,其代码具体如文件6-3-1所示。
文件6-1 User.java
package com.itheima.shiyan6_3;
import java.util.Date;
//用户信息
public class User {
private String userName; // 用户名
private String password; // 密码
private Date birthday; // 生日
private String telNumber; // 手机号码
private String email; // 邮箱
public User() {
}
public User(String userName, String password, Date birthday,
String telNumber, String email) {
this.userName = userName;
this.password = password;
this.birthday = birthday;
this.telNumber = telNumber;
this.emai* = email;
}
// 重写hashCode与equals方法
@Override
public int hashCode() {// 重写hashCode方法,以用户名作为是否重复的依据
return userName.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {// 判断是否是同一个对象
return true;// 如果是同一个对象,直接返回true
}
if (obj == null) {// 判断这个对象是否为空
return false;// 如果对象是空的,直接返回false
}
if (getClass() != obj.getClass()) {// 判断这个对象是否是User类型
return false;// 如果不是,直接返回false
}
User other = (User) obj;// 将对象强转为User类型
if (userName == null) {// 判断集合中用户名是否为空
if (other.userName != null) {// 判断对象中的用户名是否为空
// 如果集合中用户名为空并且对象中用户名不为空,则返回false
return false;
}
// 判断用户名是否相同
} else if (!userName.equals(other.userName)) {
return false;// 如果不同,返回false
}
return true;
}
}
在文件6-1中创建了一个用户类,在代码22~24行代码中重写了HashCode()方法,使其返回userName属性的哈希值,并且在代码26~47
行重写了equals()方法用于比较对象userName的属性是否相等,并返回结果。
(2) 创建用户注册类,模拟注册信息,其代码如文件6-2所示。
文件6-2 UserRegister.java
package com.itheima.shiyan6_3;
import java.util.Date;
import java.util.HashSet;
import java.util.Scanner;
public class UserRegister {
public static HashSet<User> USER_DATA = new HashSet<User>(); // 用户数据
public static void main(String[] args) {
initData();// 初始化人员信息
Scanner scan = new Scanner(System.in);
System.out.print("请输入用户名:");
String userName = scan.nextLine();// 获取用户名
System.out.print("请输入密码:");
String password = scan.nextLine();// 获取密码
System.out.print("请重复密码:");
String repassword = scan.nextLine();// 获取重复密码
System.out.print("出生日期:");
String birthday = scan.nextLine();// 获取出生日期
System.out.print("手机号码:");
String telNumber = scan.nextLine();// 获取手机号码
System.out.print("电子邮箱:");
String emai* = scan.nextLine();// 获取电子邮箱
// 校验用户信息,返回登录状态信息
CheckInfo checkInfo = new CheckInfo(USER_DATA);
String result = checkInfo.checkAction(userName, password,
repassword, birthday, telNumber, email);
System.out.println("注册结果:" + result);
}
// 初始化数据,创建两个已存在的用户信息
private static void initData() {
User user = new User("迪丽热巴", "zz,123", new Date(),
"18810319240", "[email protected]");
User user2 = new User("吴宣仪", "zq,123", new Date(),
"18618121193", "[email protected]");
USER_DATA.add(user);
USER_DATA.add(user2);
}
}
在文件6-2中,程序首先会执行第29~36行代码的initData()方法,创建“迪丽热巴”和“吴宣仪”两位用户,并将其放入到用户数据列表中,然后执行9~25
行代码,获取输入的信息并将其传入CheckInfo类的checkAction()方法对输入信息进行校验。最后将结果输出。
(3)创建校验信息类,其代码如文件6-3所示。
文件6-3 CheckInfo.java
package com.itheima.shiyan6_3;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
public class CheckInfo {
public static HashSet<User> USER_DATA = new HashSet<User>(); // 用户数据
public CheckInfo(HashSet<User> USER_DATA) {
this.USER_DATA = USER_DATA;
}
// 校验用户信息,返回登录状态信息
public String checkAction(String userName, String password,
String rePassword,String birthday, String phone, String email) {
StringBuilder result = new StringBuilder();
// 1代表成功 2代表失败
int state = 1;
// 密码判断
if (!password.equals(rePassword)) {// 判断密码和重复密码是否相同
result.append("两次输入密码不一致!\r\n");
state = 2;
}
// 生日判断
if (birthday.length() != 10) {// 字符串长度不为10,则认为格式错误
result.append("生日格式不正确!\r\n");
state = 2;
} else {
for (int i = 0; i < birthday.length(); i++) {
Character thisChar = birthday.charAt(i);
if (i == 4 || i == 7) {
if (!(thisChar == '-')) {// 验证第4位和第7位是否是
符号“-”
result.append("生日格式不正确!\r\n");
state = 2;
}
} else {// 验证除了第4位和第7位的字符是否是0~9的数字
if (!(Character.isDigit(thisChar))) {
result.append("生日格式不正确!\r\n");
state = 2;
}
}
}
}
// 手机号判断
// 判断手机号长度不等于11位则认为此手机号无效
if (phone.length() != 11) {
result.append("手机号码不正确!\r\n");
state = 2;
// 默认有效手机号为13、15、17和18开头的手机号
} else if (!(phone.startsWith("13") || phone.startsWith("15")
|| phone.startsWith("17") || phone.startsWith("18"))){
result.append("手机号码不正确!\r\n");
state = 2;
}
// 邮箱判断
// 判断邮箱地址,默认不带@符号的邮箱为无效邮箱
if (!email.contains("@")) {
result.append("邮箱不正确!\r\n");
state = 2;
}
// 如果以上信息校验无误,则将新用户加入到集合
if (state == 1) {
// 格式化日期返回Date对象
//定义日期格式
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date dateBirthday = null;
try {
// 将生日格式化成日期格式
dateBirthday = format.parse(birthday);
} catch (ParseException e) {
e.printStackTrace();
}
User newUser = new User(userName, rePassword,
dateBirthday, phone, email);
// 将用户添加到列表中,同时可根据HashSet判断出用户名有没有重复
if (!USER_DATA.add(newUser)) {
result.append("用户重复!");
state = 2;
}
if (state == 1) {
result.append("注册成功!");
}
}
return result.toString();
}
}
在文件6-3中,当主程序调用该类中的checkAction()方法后,第19~60
行代码会校验用户填写的信息,所有校验通过后,将信息创建成User对象,通过第74~75行的代码,判断用户名的哈希值是否相等。相等则添加失败,反之则成功,返回结果。
【案例6-4】 斗地主洗牌发牌
【案例介绍】
1.任务描述
扑克牌游戏“斗地主”,相信许多人都会玩,本案例要求编写一个斗地主的洗牌发牌程序,要求按照斗地主的规则完成洗牌发牌的过程。一副扑克总共有54张牌,牌面由花色和数字组成(包括J、Q、K、A字母)组成,花色有♠、♥、♦、♣ 四种,分别表示黑桃、红桃、方块、梅花,小☺、大☻分别表示小王和大王。斗地主游戏共有3位玩家参与,首先将这54张牌的顺序打乱每人轮流摸一次牌,剩余3张留作底牌,然后在控制台打印3位玩家的牌和3张底牌。
2.运行结果
任务运行结果如图6-1所示:
【任务介绍】
-
学会分析“斗地主之洗牌发牌”任务的实现思路。
-
根据思路独立完成“斗地主之洗牌发牌”任务的源代码编写、编译及运行。
-
掌握List集合和Map集合特点及常用方法的使用。
-
掌握集合遍历的方式。
【实现思路】
(1)要实现纸牌程序,首先需要完成纸牌的组装。牌面是由花色(包括♠、♥、♦、♣花色)和数字(包括J、Q、K、A字母)两部分组成,可以创建两个ArrayList集合作为花色集合与数字集合,存储时需要注意。比10大的牌的数字用J、Q、K表示,1用A表示。
(2)将花色集合与数字集合这两个循环进行嵌套循环,将花色与数字组合,形成52章牌,并赋予其编号。将组合后的牌存放到一个HashMap集合中,集合的Key值是编号,value值是组装完成的纸牌。还有两张牌是大小王(小☺表示小王、大☻表示大王)。由于组装规则不一致,需单独使用add()方法将这两张牌加入到HashMap集合中。
(3)创建一个数字集合,用这个数字集合代替纸牌完成洗牌和发牌操作。由于纸牌的数量是54张,所以创建集合范围是0~53。
(4)可以使用Collection类的shuffle()方法完成打乱数字集合的操作,实现洗牌效果。由于只有3个人,所以可以使用for循环,通过将数字与3取余的方法,将代表不同纸牌的数字分配给不同人与底牌,实现发牌效果。
(5) 洗牌和发牌结束后,可以通过Collection类的sort()方法完成排序,之后通过foreach()循环HashMap集合,根据数字查找对应的纸牌字符串,并存入创建的字符串集合中,最后展示字符串集合。
【实现代码】
程序实现代码如文件6-1所示。
文件6-1 example5.java
package com.itheima;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
public class example5 {
public static void main(String[] args) {
// 准备花色
ArrayList<String> color = new ArrayList<String>();
color.add("♠");
color.add("♥");
color.add("♦");
color.add("♣");
// 准备数字 ,用ArrayList将纸牌由小到大排序
ArrayList<String> number = new ArrayList<String>();
for (int i = 3; i <= 10; i++) {
number.add(i + "");
}
number.add("J");
number.add("Q");
number.add("K");
number.add("A");
number.add("2");
// 定义一个map集合:用来将数字与每一张牌进行对应
HashMap<Integer, String> map = new HashMap<Integer, String>();
int index = 0;// 纸牌编号
for (String thisNumber : number) {// 循环纸牌数字
for (String thisColor : color) {// 循环纸牌花色
// 将花色与数字组合,形成52张牌,并赋予其编号
map.put(index++, thisColor + thisNumber);
}
}
// 加入大小王
map.put(index++, "小☺");
map.put(index++, "大☻");
// 一副54张的牌 ArrayList里边为0-53的数的新牌
ArrayList<Integer> cards = new ArrayList<Integer>();
for (int i = 0; i <= 53; i++) {
cards.add(i);// 此时的cards顺序为0-53
}
// 洗牌,使用Collections工具类中的shuffle()方法
Collections.shuffle(cards);// 此时的cards顺序已被打乱
// 创建三个玩家和底牌
ArrayList<Integer> iPlayer = new ArrayList<Integer>();
ArrayList<Integer> iPlayer2 = new ArrayList<Integer>();
ArrayList<Integer> iPlayer3 = new ArrayList<Integer>();
ArrayList<Integer> iSecretCards = new ArrayList<Integer>();
// 遍历这副洗好的牌,遍历过程中,将牌发到三个玩家和底牌中
for (int i = 0; i < cards.size(); i++) {
if (i >= 51) {
iSecretCards.add(cards.get(i));// 留取3张底牌
} else {
if (i % 3 == 0) {
iPlayer.add(cards.get(i));//与3取余为0的牌发给玩家1
} else if (i % 3 == 1) {
iPlayer2.add(cards.get(i));//与3取余为1的牌发给玩家2
} else {
iPlayer3.add(cards.get(i));// 其余的牌发给玩家3
}
}
}
// 对每个人手中的牌排序,使用Collections工具类中的sort()方法
Collections.sort(iPlayer);
Collections.sort(iPlayer2);
Collections.sort(iPlayer3);
// 对应数字形式的每个人手中的牌,定义字符串形式的牌
ArrayList<String> sPlayer = new ArrayList<String>();
ArrayList<String> sPlayer2 = new ArrayList<String>();
ArrayList<String> sPlayer3 = new ArrayList<String>();
ArrayList<String> sSecretCards = new ArrayList<String>();
// 循环主键,从map中获取纸牌
for (Integer key : iPlayer) {
sPlayer.add(map.get(key));
}
for (Integer key : iPlayer2) {
sPlayer2.add(map.get(key));
}
for (Integer key : iPlayer3) {
sPlayer3.add(map.get(key));
}
for (Integer key : iSecretCards) {
sSecretCards.add(map.get(key));
}
// 看牌
System.out.println("玩家1:" + sPlayer);
System.out.println("玩家2:" + sPlayer2);
System.out.println("玩家3:" + sPlayer3);
System.out.println("底牌:" + sSecretCards);
}
}
在文件6-1中,第8~22
行代码将4种花色和13个纸牌编号分别放到两个ArrayList集合中。第24~34
当代码foreach循环拼出52张纸牌,并将其依照从小到大的顺序放入Map集合中,并将大小王添加到其中。
第36~41
行代码创建了代替纸牌的数字集合,将其与纸牌中的序号对应,并将数字集合中的顺序打乱,此时集合相当于纸牌编号集合。第43~60
行代码完成了将纸牌编号发给3位玩家并留3张纸牌编号做为底牌的操作。
第62~64行代码将3位玩家手中纸牌编号进行排序。第66~88
行代码通过循环3位玩家手中的纸牌编号,将纸牌字符串从Map中取出放入字符串集合。最后打印字符串集合,分别得到3个玩家的纸牌和底牌。
【案例6-5】 模拟百度翻译
【案例介绍】
1.任务描述
大家对百度翻译并不陌生,本案例要求编写一个程序模拟百度翻译。用户输入英文之后搜索程序中对应的中文,如果搜索到对应的中文就输出搜索结果,反之给出提示。本案例要求使用Map集合实现英文与中文的存储。
2.运行结果
程序运行结果如图6-1所示:
【案例任务】
-
学会分析“模拟百度翻译”任务的实现思路。
-
根据思路独立完成“模拟百度翻译”任务的源代码编写、编译及运行。
-
掌握Map集合特点及常用方法的使用。
【案例思路】
(1)百度翻译主要用于翻译对应的意思。这是一种映射关系。因此可以用 Map集合来实现,所以首先就是定义Map集合,存储数据。
(2)用键盘录入功能获取我们要翻译的单词。
(3)定义一个方法,在该方法中实现对单词的查询操作,并且根据不同情况给出相关提示。
(4)调用查询的方法,实现翻译。并将结果输出到控制台。
【案例实现】
程序实现代码如文件6-1所示。
文件6-1 example7.java
package com.itheima;
import java.util.HashMap;
import java.util.Scanner;
public class example7 {
public static void main(String[] args) {
//定义Map集合用于存储词典的数据
HashMap<String, String> word = new HashMap<String, String>();
while(true) {
//集合合添加词典的数据。
word.put("apple", "苹果");
word.put("banner", "香蕉");
word.put("book", "书");
word.put("telephone", "电话");
word.put("cat", "猫");
word.put("dog", "狗");
word.put("student", "学生");
word.put("teacher", "老师");
//键盘录入功能获取我们要翻译的单词
Scanner sc = new Scanner(System.in);
System.out.println("请您输入您要翻译的单词:");
String w = sc.nextLine();
//调用判断打印输出
Select(w, word);
}
}
//定义方法对键盘录入的数据进行判断
public static String Select(String w, HashMap<String, String> word) {
if(w.isEmpty()) {
System.out.println("请输入您要翻译的单词:");
return "";
}else if(!word.containsKey(w)) {
System.out.println("对不起,您要翻译的单词不存在,请重新输入:");
}else{
String chinese = word.get(w);
System.out.println(w+"翻译成中文意思为:"+chinese);
}
return w;
}
}
在文件6-1中,第7行代码用于定义HashMap集合。第10~17
行代码用Map集合的put()方法向集合中添加词典的初始化数据。第19~21
行代码键盘录入我们要翻译的英文单词,第23行代码调用Select()方法实现集合中判断是否包含键盘输入的单词,如果有则输入对应的中文意思,反之则给出相应提示。