系统需求
- 总需求
- 系统界面展示
2.1 主菜单
2.2 新增房源
2.3 查找房源
2.4 删除房源
2.5 修改房源
2.6 房屋列表
2.7 退出系统
2.1 主菜单
2.2 新增房源
2.3 查找房源
2.4 删除房源
2.5 修改房源
2.6 房屋列表
2.7 退出系统
项目设计
分层模式(界面层,业务层,model层):
一、工具类
-
工具类介绍
-
注意:静态方法可以直接通过类名调用
-
工具类代码
package com.wpangzi.houserent.utils;
/**
工具类的作用:
处理各种情况的用户输入,并且能够按照程序员的需求,得到用户的控制台输入。
*/
import java.util.*;
public class Utility {
//静态属性。。。
private static Scanner scanner = new Scanner(System.in);
/**
* 功能:读取键盘输入的一个菜单选项,值:1——5的范围
* @return 1——5
*/
public static char readMenuSelection() {
char c;
for (; ; ) {
String str = readKeyBoard(1, false);//包含一个字符的字符串
c = str.charAt(0);//将字符串转换成字符char类型
if (c != '1' && c != '2' &&
c != '3' && c != '4' && c != '5') {
System.out.print("选择错误,请重新输入:");
} else break;
}
return c;
}
/**
* 功能:读取键盘输入的一个字符
* @return 一个字符
*/
public static char readChar() {
String str = readKeyBoard(1, false);//就是一个字符
return str.charAt(0);
}
/**
* 功能:读取键盘输入的一个字符,如果直接按回车,则返回指定的默认值;否则返回输入的那个字符
* @param defaultValue 指定的默认值
* @return 默认值或输入的字符
*/
public static char readChar(char defaultValue) {
String str = readKeyBoard(1, true);//要么是空字符串,要么是一个字符
return (str.length() == 0) ? defaultValue : str.charAt(0);
}
/**
* 功能:读取键盘输入的整型,长度小于2位
* @return 整数
*/
public static int readInt() {
int n;
for (; ; ) {
String str = readKeyBoard(10, false);//一个整数,长度<=10位
try {
n = Integer.parseInt(str);//将字符串转换成整数
break;
} catch (NumberFormatException e) {
System.out.print("数字输入错误,请重新输入:");
}
}
return n;
}
/**
* 功能:读取键盘输入的 整数或默认值,如果直接回车,则返回默认值,否则返回输入的整数
* @param defaultValue 指定的默认值
* @return 整数或默认值
*/
public static int readInt(int defaultValue) {
int n;
for (; ; ) {
String str = readKeyBoard(10, true);
if (str.equals("")) {
return defaultValue;
}
//异常处理...
try {
n = Integer.parseInt(str);
break;
} catch (NumberFormatException e) {
System.out.print("数字输入错误,请重新输入:");
}
}
return n;
}
/**
* 功能:读取键盘输入的指定长度的字符串
* @param limit 限制的长度
* @return 指定长度的字符串
*/
public static String readString(int limit) {
return readKeyBoard(limit, false);
}
/**
* 功能:读取键盘输入的指定长度的字符串或默认值,如果直接回车,返回默认值,否则返回字符串
* @param limit 限制的长度
* @param defaultValue 指定的默认值
* @return 指定长度的字符串
*/
public static String readString(int limit, String defaultValue) {
String str = readKeyBoard(limit, true);
return str.equals("")? defaultValue : str;
}
/**
* 功能:读取键盘输入的确认选项,Y或N
* 将小的功能,封装到一个方法中.
* @return Y或N
*/
public static char readConfirmSelection() {
System.out.println("请输入你的选择(Y/N): 请小心选择");
char c;
for (; ; ) {//无限循环
//在这里,将接受到字符,转成了大写字母
//y => Y n=>N
String str = readKeyBoard(1, false).toUpperCase();
c = str.charAt(0);
if (c == 'Y' || c == 'N') {
break;
} else {
System.out.print("选择错误,请重新输入:");
}
}
return c;
}
/**
* 功能: 读取一个字符串
* @param limit 读取的长度
* @param blankReturn 如果为true ,表示 可以读空字符串。
* 如果为false表示 不能读空字符串。
*
* 如果输入为空,或者输入大于limit的长度,就会提示重新输入。
* @return
*/
private static String readKeyBoard(int limit, boolean blankReturn) {
//定义了字符串
String line = "";
//scanner.hasNextLine() 判断有没有下一行
while (scanner.hasNextLine()) {
line = scanner.nextLine();//读取这一行
//如果line.length=0, 即用户没有输入任何内容,直接回车
if (line.length() == 0) {
if (blankReturn) return line;//如果blankReturn=true,可以返回空串
else continue; //如果blankReturn=false,不接受空串,必须输入内容
}
//如果用户输入的内容大于了 limit,就提示重写输入
//如果用户如的内容 >0 <= limit ,我就接受
if (line.length() < 1 || line.length() > limit) {
System.out.print("输入长度(不能大于" + limit + ")错误,请重新输入:");
continue;
}
break;
}
return line;
}
}
二、编写House类
- 找属性
根据房屋列表可知基本属性有这6个
- 代码
- 私有属性
- 构造器
- get和set方法
- 重写toString方法(按照自己需要的输出)
package com.wpangzi.houserent.domain;
/**
* House的对象表示一个基本信息
*/
public class House {
//编号,房主,电话,地址,月租,状态(已出租/未出租)
private int id;
private String name;
private String phone;
private String address;
private int rent;
private String state;
//构造器和get。set方法
public House(int id, String name, String phone, String address, int rent, String state) {
this.id = id;
this.name = name;
this.phone = phone;
this.address = address;
this.rent = rent;
this.state = state;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getRent() {
return rent;
}
public void setRent(int rent) {
this.rent = rent;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
//按照房屋列表重写toString方法
@Override
public String toString() {
return id +
"\t" + name +
"\t" + phone +
"\t" + address +
"\t" + rent +
"\t" + state;
}
}
三、实现主菜单
- 总要求
- 实现分析
- 代码编写
package com.wpangzi.houserent.view;
import com.wpangzi.houserent.utils.Utility;
import java.util.Scanner;
/**
* 步骤是:
* 1. 显示界面(输出界面提示内容)
* 2. 接受用户输入(key)
* 3. 调用HouseService完成对房屋信息的各种操作(用switch-case)
*/
public class HouseView {
//属性
private char key = ' ';//接收用户选择
private boolean loop = true;//控制显示菜单
//显示主菜单
public void mainMenu(){
do {
System.out.println("========房屋出租系统========");
System.out.println("\t\t1 新 增 房 源");
System.out.println("\t\t2 查 找 房 屋");
System.out.println("\t\t3 删除房屋信息");
System.out.println("\t\t4 修改房屋信息");
System.out.println("\t\t5 房屋列表");
System.out.println("\t\t6 退出");
System.out.print("请选择(1-6):");
key = Utility.readChar();
//注意这个key是字符不是数字!!
switch (key){
case '1':
System.out.println("--------添加房屋--------");
System.out.println("--------添加完成--------");
break;
case '2':
System.out.println("--------查找房屋--------");
break;
case '3':
System.out.println("--------删除房屋--------");
System.out.println("--------删除完成--------");
break;
case '4':
System.out.println("--------修改房屋--------");
System.out.println("--------修改完成--------");
break;
case '5':
System.out.println("--------房屋列表--------");
System.out.println("--------房屋列表完成--------");
break;
case '6':
loop = false;
break;
//总是忘记写默认
default:
System.out.println("输入错误");
break;
}
}while (loop);
//如果退出while循环,说明退出了程序
System.out.println("你退出了程序~~");
}
}
package com.wpangzi.houserent;
import com.wpangzi.houserent.utils.Utility;
import com.wpangzi.houserent.view.HouseView;
public class HouseRentAPP {
public static void main(String[] args) {
//创建HouseView对象,并且显示主菜单,是整个程序的入口
/*
这样显得很罗嗦,可以使用匿名对象直接调用
HouseView houseView = new HouseView();
houseView.mainMenu();
*/
new HouseView().mainMenu();
}
}
四、实现房屋出租列表
- 功能描述
- 实现分析
① 房屋列表中数据的显示的格式需要在view中写且需调用业务层中返回数据的方法
② 业务层中需要定义数组,再给一个返回数组的方法
- 代码编写
① 界面层(此部分-非全部)
- 显示界面部分
- 接收业务层返回的数据并遍历
- 注意遍历时对于null数据的处理 - 没有嵌套而是把不要的部分直接break
- 在switch中调用列表
//创建HouseService对象来调用list方法,初始化HouseService对象(数组长度为10)
private HouseService houseService = new HouseService(10);
//...中间部分重复
case '5':
listHouse();
break;
//编写listHouse(),显示房屋列表
public void listHouse(){
System.out.println("--------房屋列表--------");
System.out.println("编号\t房主\t\t电话\t\t\t地址\t\t月租\t\t状态(已出租/未出租)");
House[] houses = houseService.list();//接收返回的House数组
//遍历数组
for (int i = 0; i < houses.length; i++) {
/*
如果元素为空,则不用显示了
这里没有判断houses[i] != null则输出,为了少嵌套,少耦合
*/
if (houses[i] == null) {
break;
}
System.out.println(houses[i].toString());
}
System.out.println("--------房屋列表完成--------");
}
② 业务层
- 零钱通例子用到的是字符串拼接
因为列表中属性显示的格式不是按照对象的属性来的,做了修改- 房屋出租这个例子用的是数组
因为列表中属性显示的格式就是按对象属性来的,直接用实体类中的toString方法输出即可
toString方法重写 - 写成列表需要的格式- 在构造器中,当创建HouseService对象时,指定数组的大小
- 返回数组,让view中接受数组并遍历、显示
package com.wpangzi.houserent.service;
import com.wpangzi.houserent.domain.House;
/**
* HouseService[业务层]
* //定义House[],保存House对象
* 1. 响应HouseView的调用
* 2. 完成对房屋信息的各种操作(crud)
*/
public class HouseService {
//属性
/*
1. 零钱通例子用到的是字符串拼接
因为列表中属性显示的格式不是按照对象的属性来的,做了修改
2. 房屋出租这个例子用的是数组
因为列表中属性显示的格式就是按对象属性来的,直接用实体类中的toString方法输出即可
toString方法重写 - 写成列表需要的格式
*/
private House[] houses;//保存House对象
//方法
/*
构造器
1. House[]数组只初始化没有在堆中创建(因为不知道数组的大小)
2. 当创建HouseService对象时,指定数组的大小
*/
public HouseService(int size) {
houses = new House[size];
//为了配合测试,所以先初始化一个对象
houses[0] = new House(1, "王胖子", "15800001111",
"中国×××", 2000, "未出租");
}
//list方法,返回houses数组
public House[] list(){
return houses;
}
}
- 效果
五、实现添加房屋
-
总要求
-
实现分析
-
代码编写
- 把新增的房屋添加到数组中然后houseNums加1
houseNums表示数组中已经有几个元素,用于判断是否需要扩容和当元素下标
第一种:
houses[houseNums] = newHouse;
houseNums++;
第二种:
houses[houseNums++] = newHouse;- 实现id自增长机制,然后更新newHouse的id
第一种:
idCounter++;
newHouse.setId(idCounter);
第二种:(先加后赋值)
newHouse.setId(++idCounter);- 数组扩充:house去接收调用数组扩充方法后返回的新数组(不能在方法中新数组赋值给旧数组,在方法外还是按原数组的…)
service节选部分代码
private House[] houses;//保存House对象
private int houseNums = 1;//记录当前有多少个房屋信息
private int idCounter = 1;//id计数器,记录当前id到哪个值
//add方法,添加新对象,返回Boolean
public boolean add(House newHouse){
//判断是否还可以继续添加(我们暂时不考虑数组扩容的问题)
// if (houseNums == houses.length){//不能再添加
// System.out.println("数组已满,不能再添加");
// return false;
// }
//考虑数组扩容
if (houseNums >= houses.length){//调用数组扩容方法,数组扩1
houses = copyHouse(houses);
}
/*
把新增的房屋添加到数组中,然后houseNums加1
第一种:
houses[houseNums] = newHouse;
houseNums++;
第二种:
houses[houseNums++] = newHouse;
*/
houses[houseNums++] = newHouse;
/*
实现id自增长机制,然后更新newHouse的id
第一种:
idCounter++;
newHouse.setId(idCounter);
第二种:(先加后赋值)
newHouse.setId(++idCounter);
*/
newHouse.setId(++idCounter);
return true;
}
//实现数组扩容
public House[] copyHouse(House[] houses){
House[] houses1 = new House[houses.length+1];
for (int i = 0; i < houses.length; i++) {
houses1[i] = houses[i];
}
return houses1;
}
view节选部分代码
case '1':
addHouse();
break;
//编写addHouse(),接受输入,创建House对象,调用add方法
public void addHouse(){
System.out.println("--------------------------添加房屋--------------------------");
System.out.printf("姓名:");
String name = Utility.readString(10);
System.out.printf("电话:");
String phone = Utility.readString(11);
System.out.printf("地址:");
String address = Utility.readString(20);
System.out.printf("月租:");
int rent = Utility.readInt(6);
System.out.printf("状态(未出租/已出租):");
String state = Utility.readString(3);
//创建一个新的House对象,注意id是系统分配的(自增长),这里先写成0
House newHouse = new House(0,name,phone,address,rent,state);
if (houseService.add(newHouse)){
System.out.println("--------------------------添加完成--------------------------");
}else{
System.out.println("--------------------------添加失败--------------------------");
}
}
- 效果
六、实现房屋删除
- 总要求
- 实现分析
- 代码
service截取部分代码
//del(),删除一个房屋信息
public boolean del(int delId){
/*
1. 应当先找到要删除的房屋信息对相应的下标
2. 注意:下标和房屋编号不是一个东西(各司其职)
3. houseNums是指现在有多少个房屋信息,比如有2个
4. 而数组有多大,下标就有多少个,比如定义数组长度是10,则下标可以为10
*/
int index = -1;//用于接收id对应数组的下标
for (int i = 0; i < houseNums; i++) {//要删除的房屋(id),是数组下标未i的元素
if (delId == houses[i].getId()){
index = delId;
}
}
if (index == -1){//说明delId不存在
return false;
}
/*
1. 如果找到,则从下标index开始,每个元素前移,最后一个元素置空
(这里的最后一个是指当前存在信息的最后一个)
2. 后一个元素覆盖前一个,最后一个下标不参与循环,因为再加1就是空值或者越界了
3. 删除之后要把houseNums--!!!
3.1 第一种
houses[houseNums-1] = null;
houseNums --;//少一个
3.2 第二种(这种自加加,自减减用很多的,如果要用到自增自减的要想到这个)
houses[--houseNums] = null;
*/
for (int i = index; i < houseNums - 1; i++) {
houses[i] = houses[i+1];
}
houses[--houseNums] = null;
return true;
}
view截取部分代码
if (houseService.del(delId))
方法返回布尔值,在view类中调用并判断真假,然后输出界面的内容(service类中只写了删除的逻辑然后返回布尔值,让view类去判断真假输出界面内容)
case '3':
delHouse();
break;
//编写delHouse(),接收输入的id,调用Service的del方法
public void delHouse(){
System.out.println("--------------------------删除房屋--------------------------");
System.out.print("请输入待删除房屋的编号(-1退出):");
int delId = Utility.readInt();
if (delId == -1){
System.out.println("-------------------------放弃删除房屋-------------------------");
return;
}
//注意该方法本身就有循环判断的逻辑,必须输入Y/N,且自己输出了提示语句
char choice = Utility.readConfirmSelection();
if (choice == 'Y'){
if (houseService.del(delId)){
System.out.println("--------------------------删除成功--------------------------");
}else {
System.out.println("-----------------------没有该编号,删除失败-----------------------");
}
}else {
System.out.println("-------------------------放弃删除房屋-------------------------");
}
}
- 输出效果
七、实现退出系统
- 总要求
- 代码
view部分
//完成退出确认
public void exitHouse(){
System.out.printf("确认退出吗(Y/N):");
//choice会接收到一个Y/N
char choice = Utility.readConfirmSelection();
if (choice == 'Y'){
loop = false;
}else {
System.out.println("--------------------------放弃退出--------------------------");
}
}
- 输出效果
八、实现根据id查找(多看看)
-
总要求
-
实现分析
-
代码
service部分代码
//findById(),返回House对象或者null
public House findById(int findId) {
/*
findId和已有数据的id进行匹配,若匹配上则输出信息
一定注意是和数组元素的id比较而不是和数组元素的下标比较!!!
如果找到就返回这个house对象,如果没找到则返回空
(比我那个返回当前下标然后使用get方法获取house对象的方法好)
*/
for (int i = 0; i < houseNums; i++) {
if (findId == houses[i].getId()) {
return houses[i];
}
}
return null;
}
view部分代码
//根据id查找房屋信息
public void findHouse() {
System.out.println("--------------------------查找房屋--------------------------");
System.out.printf("请输入你要查找的id:");
int findId = Utility.readInt();
//调用方法
/*
这是我没听老师讲之前用的方法,不太好
1. 我调用方法接收了id对应的下标,然后用get方法获取house数组对应下标的信息
2. 输出对象会自动调用toString方法System.out.println(house);
int result =houseService.findById(findId);
if (result != -1) {
System.out.println(houseService.getHouses()[result].toString());
} else {
System.out.println("-------------------------没有该房屋--------------------------");
}
*/
House house = houseService.findById(findId);
if (house != null) {
System.out.println(house);
} else {
System.out.println("------------------------该id不存在-------------------------");
}
}
- 输出效果
九、实现修改房屋
- 总要求
- 实现分析
- 代码
service代码用的是findById的代码
view中部分代码
输入可以为空,所以要加一个判断
判断输入接收内容是否为空,不为空则修改,否则什么都不做
//根据id修改房屋信息
public void updateHouse() {
System.out.println("-------------------------修改房屋信息-------------------------");
System.out.printf("请选择待修改房屋编号(-1退出):");
int updateId = Utility.readInt();
if (updateId == -1) {
System.out.println("--------------------------放弃修改--------------------------");
return;
}
/*
调用方法,方法会根据id 返回对象或null
当判断里面的代码很多时,要想到可以使用过关斩将的思想
先写出不正确的然后return
这样正确的内容就不会嵌套在条件语句中
下面是没听老师讲之前写的,条件语句中内容过多,没有想到过关斩将的思想
且我返回的是id 对应数组的下标
*/
// int index = houseService.update(updateId);
// if (index != -1) {
// System.out.printf("姓名(" + houseService.getHouses()[index].getName() + "):");
// String name = Utility.readString(5, "");
// houseService.getHouses()[index].setName(name);
// System.out.printf("电话(" + houseService.getHouses()[index].getPhone() + "):");
// String phone = Utility.readString(11, "13588889999");
// System.out.printf("地址(" + houseService.getHouses()[index].getAddress() + "):");
// String address = Utility.readString(11, "中国***");
// System.out.printf("租金(" + houseService.getHouses()[index].getRent() + "):");
// int rent = Utility.readInt(1000);
// System.out.printf("状态(" + houseService.getHouses()[index].getState() + "):");
// String state = Utility.readString(3, "未出租");
// System.out.println("--------------------------修改成功--------------------------");
// } else {
// System.out.println("-------------------------不存在该房屋-------------------------");
// }
House house = houseService.findById(updateId);
if (house == null) {
System.out.println("----------------------修改房屋信息的编号不存在----------------------");
return;
}
System.out.printf("姓名(" + house.getName() + "):");
String name = Utility.readString(5, "");
if (!"".equals(name)) {//如果name非空,则修改
house.setName(name);
}
System.out.printf("电话(" + house.getPhone() + "):");
String phone = Utility.readString(11, "");
if (!"".equals(phone)) {//如果name非空,则修改
house.setPhone(phone);
}
System.out.printf("地址(" + house.getAddress() + "):");
String address = Utility.readString(11, "");
if (!"".equals(address)) {//如果name非空,则修改
house.setAddress(address);
}
System.out.printf("租金(" + house.getRent() + "):");
int rent = Utility.readInt(-1);
if (rent != -1) {//如果name非空,则修改
house.setRent(rent);
}
System.out.printf("状态(" + house.getState() + "):");
String state = Utility.readString(3, "");
if (!"".equals(state)) {//如果name非空,则修改
house.setState(state);
}
System.out.println("--------------------------修改成功--------------------------");
}
- 输出效果
整体代码
- HouseRentAPP.java
package com.wpangzi.houserent;
import com.wpangzi.houserent.utils.Utility;
import com.wpangzi.houserent.view.HouseView;
public class HouseRentAPP {
public static void main(String[] args) {
//创建HouseView对象,并且显示主菜单,是整个程序的入口
/*
这样显得很罗嗦,可以使用匿名对象直接调用
HouseView houseView = new HouseView();
houseView.mainMenu();
*/
new HouseView().mainMenu();
}
}
- HouseView.java
package com.wpangzi.houserent.view;
import com.wpangzi.houserent.domain.House;
import com.wpangzi.houserent.service.HouseService;
import com.wpangzi.houserent.utils.Utility;
import java.util.Scanner;
/**
* 步骤是:
* 1. 显示界面(输出界面提示内容)
* 2. 接受用户输入(key)
* 3. 调用HouseService完成对房屋信息的各种操作(用switch-case)
*/
public class HouseView {
//属性
private char key = ' ';//接收用户选择
private boolean loop = true;//控制显示菜单
//创建HouseService对象来调用list方法,初始化HouseService对象(数组长度为10)
private HouseService houseService = new HouseService(2);
//显示主菜单
public void mainMenu() {
do {
System.out.println("========房屋出租系统========");
System.out.println("\t\t1 新 增 房 源");
System.out.println("\t\t2 查 找 房 屋");
System.out.println("\t\t3 删除房屋信息");
System.out.println("\t\t4 修改房屋信息");
System.out.println("\t\t5 房屋列表");
System.out.println("\t\t6 退出");
System.out.print("请选择(1-6):");
key = Utility.readChar();
//注意这个key是字符不是数字!!
switch (key) {
case '1':
addHouse();
break;
case '2':
findHouse();
break;
case '3':
delHouse();
break;
case '4':
updateHouse();
break;
case '5':
listHouse();
break;
case '6':
exitHouse();
break;
//总是忘记写默认
default:
System.out.println("输入错误");
break;
}
} while (loop);
//如果退出while循环,说明退出了程序
System.out.println("你退出了程序~~");
}
//编写listHouse(),显示房屋列表
public void listHouse() {
System.out.println("--------------------------房屋列表-------------------------");
System.out.println("编号\t房主\t\t电话\t\t\t地址\t\t月租\t\t状态(已出租/未出租)");
House[] houses = houseService.list();//接收返回的House数组
//遍历数组
for (int i = 0; i < houses.length; i++) {
/*
如果元素为空,则不用显示了
这里没有判断houses[i] != null则输出,为了少嵌套,少耦合
*/
if (houses[i] == null) {
break;
}
System.out.println(houses[i].toString());
}
System.out.println("------------------------房屋列表完成------------------------");
}
//编写addHouse(),接受输入,创建House对象,调用add方法
public void addHouse() {
System.out.println("--------------------------添加房屋--------------------------");
System.out.printf("姓名:");
String name = Utility.readString(10);
System.out.printf("电话:");
String phone = Utility.readString(11);
System.out.printf("地址:");
String address = Utility.readString(20);
System.out.printf("月租:");
int rent = Utility.readInt(6);
System.out.printf("状态(未出租/已出租):");
String state = Utility.readString(3);
//创建一个新的House对象,注意id是系统分配的(自增长),这里先写成0
House newHouse = new House(0, name, phone, address, rent, state);
if (houseService.add(newHouse)) {
System.out.println("--------------------------添加完成--------------------------");
} else {
System.out.println("--------------------------添加失败--------------------------");
}
}
//编写delHouse(),接收输入的id,调用Service的del方法
public void delHouse() {
System.out.println("--------------------------删除房屋--------------------------");
System.out.print("请输入待删除房屋的编号(-1退出):");
int delId = Utility.readInt();
if (delId == -1) {
System.out.println("-------------------------放弃删除房屋-------------------------");
return;
}
//注意该方法本身就有循环判断的逻辑,必须输入Y/N
System.out.print("请小心选择:请输入你的选择(Y/N): ");
char choice = Utility.readConfirmSelection();
if (choice == 'Y') {
if (houseService.del(delId)) {
System.out.println("--------------------------删除成功--------------------------");
} else {
System.out.println("-----------------------没有该编号,删除失败-----------------------");
}
} else {
System.out.println("-------------------------放弃删除房屋-------------------------");
}
}
//完成退出确认
public void exitHouse() {
System.out.printf("确认退出吗(Y/N):");
//choice会接收到一个Y/N
char choice = Utility.readConfirmSelection();
if (choice == 'Y') {
loop = false;
} else {
System.out.println("--------------------------放弃退出--------------------------");
}
}
//根据id查找房屋信息
public void findHouse() {
System.out.println("--------------------------查找房屋--------------------------");
System.out.printf("请输入你要查找的id:");
int findId = Utility.readInt();
//调用方法
/*
这是我没听老师讲之前用的方法,不太好
1. 我调用方法接收了id对应的下标,然后用get方法获取house数组对应下标的信息
2. 输出对象会自动调用toString方法System.out.println(house);
int result =houseService.findById(findId);
if (result != -1) {
System.out.println(houseService.getHouses()[result].toString());
} else {
System.out.println("-------------------------没有该房屋--------------------------");
}
*/
House house = houseService.findById(findId);
if (house != null) {
System.out.println(house);
} else {
System.out.println("------------------------该id不存在-------------------------");
}
}
//根据id修改房屋信息
public void updateHouse() {
System.out.println("-------------------------修改房屋信息-------------------------");
System.out.printf("请选择待修改房屋编号(-1退出):");
int updateId = Utility.readInt();
if (updateId == -1) {
System.out.println("--------------------------放弃修改--------------------------");
return;
}
/*
调用方法,方法会根据id 返回对象或null
当判断里面的代码很多时,要想到可以使用过关斩将的思想
先写出不正确的然后return
这样正确的内容就不会嵌套在条件语句中
下面是没听老师讲之前写的,条件语句中内容过多,没有想到过关斩将的思想
且我返回的是id 对应数组的下标
*/
// int index = houseService.update(updateId);
// if (index != -1) {
// System.out.printf("姓名(" + houseService.getHouses()[index].getName() + "):");
// String name = Utility.readString(5, "");
// houseService.getHouses()[index].setName(name);
// System.out.printf("电话(" + houseService.getHouses()[index].getPhone() + "):");
// String phone = Utility.readString(11, "13588889999");
// System.out.printf("地址(" + houseService.getHouses()[index].getAddress() + "):");
// String address = Utility.readString(11, "中国***");
// System.out.printf("租金(" + houseService.getHouses()[index].getRent() + "):");
// int rent = Utility.readInt(1000);
// System.out.printf("状态(" + houseService.getHouses()[index].getState() + "):");
// String state = Utility.readString(3, "未出租");
// System.out.println("--------------------------修改成功--------------------------");
// } else {
// System.out.println("-------------------------不存在该房屋-------------------------");
// }
House house = houseService.findById(updateId);
if (house == null) {
System.out.println("----------------------修改房屋信息的编号不存在----------------------");
return;
}
System.out.printf("姓名(" + house.getName() + "):");
String name = Utility.readString(5, "");
if (!"".equals(name)) {//如果name非空,则修改
house.setName(name);
}
System.out.printf("电话(" + house.getPhone() + "):");
String phone = Utility.readString(11, "");
if (!"".equals(phone)) {//如果name非空,则修改
house.setPhone(phone);
}
System.out.printf("地址(" + house.getAddress() + "):");
String address = Utility.readString(11, "");
if (!"".equals(address)) {//如果name非空,则修改
house.setAddress(address);
}
System.out.printf("租金(" + house.getRent() + "):");
int rent = Utility.readInt(-1);
if (rent != -1) {//如果name非空,则修改
house.setRent(rent);
}
System.out.printf("状态(" + house.getState() + "):");
String state = Utility.readString(3, "");
if (!"".equals(state)) {//如果name非空,则修改
house.setState(state);
}
System.out.println("--------------------------修改成功--------------------------");
}
}
- HouseService.java
package com.wpangzi.houserent.service;
import com.wpangzi.houserent.domain.House;
/**
* HouseService[业务层]
* //定义House[],保存House对象
* 1. 响应HouseView的调用
* 2. 完成对房屋信息的各种操作(crud)
*/
public class HouseService {
//属性
/*
1. 零钱通例子用到的是字符串拼接
因为列表中属性显示的格式不是按照对象的属性来的,做了修改
2. 房屋出租这个例子用的是数组
因为列表中属性显示的格式就是按对象属性来的,直接用实体类中的toString方法输出即可
toString方法重写 - 写成列表需要的格式
*/
private House[] houses;//保存House对象
private int houseNums = 2;//记录当前有多少个房屋信息
private int idCounter = 2;//id计数器,记录当前id到哪个值
//方法
/*
构造器
1. House[]数组只初始化没有在堆中创建(因为不知道数组的大小)
2. 当创建HouseService对象时,指定数组的大小
*/
public HouseService(int size) {
houses = new House[size];
//为了配合测试,所以先初始化一个对象
houses[0] = new House(1, "王胖子", "15800001111",
"中国×××", 2000, "未出租");
houses[1] = new House(2, "高瘦子", "13811115555",
"平遥县", 1000, "已出租");
}
//list方法,返回houses数组
public House[] list() {
return houses;
}
//add方法,添加新对象,返回Boolean
public boolean add(House newHouse) {
//判断是否还可以继续添加(我们暂时不考虑数组扩容的问题)
// if (houseNums == houses.length){//不能再添加
// System.out.println("数组已满,不能再添加");
// return false;
// }
//考虑数组扩容
if (houseNums >= houses.length) {//调用数组扩容方法,数组扩1
houses = copyHouse(houses);
}
/*
把新增的房屋添加到数组中,然后houseNums加1
第一种:
houses[houseNums] = newHouse;
houseNums++;
第二种:
houses[houseNums++] = newHouse;
*/
houses[houseNums++] = newHouse;
/*
实现id自增长机制,然后更新newHouse的id
第一种:
idCounter++;
newHouse.setId(idCounter);
第二种:(先加后赋值)
newHouse.setId(++idCounter);
*/
newHouse.setId(++idCounter);
return true;
}
//实现数组扩容
public House[] copyHouse(House[] houses) {
House[] houses1 = new House[houses.length + 1];
for (int i = 0; i < houses.length; i++) {
houses1[i] = houses[i];
}
return houses1;
}
//del(),删除一个房屋信息
public boolean del(int delId) {
/*
1. 应当先找到要删除的房屋信息对相应的下标
2. 注意:下标和房屋编号不是一个东西(各司其职)
3. houseNums是指现在有多少个房屋信息,比如有2个
4. 而数组有多大,下标就有多少个,比如定义数组长度是10,则下标可以为10
*/
int index = -1;//用于接收id对应数组的下标
for (int i = 0; i < houseNums; i++) {//要删除的房屋(id),是数组下标未i的元素
if (delId == houses[i].getId()) {
index = i;
}
}
if (index == -1) {//说明delId不存在
return false;
}
/*
1. 如果找到,则从下标index开始,每个元素前移,最后一个元素置空
(这里的最后一个是指当前存在信息的最后一个)
2. 后一个元素覆盖前一个,最后一个下标不参与循环,因为再加1就是空值或者越界了
3. 删除之后要把houseNums--!!!
3.1 第一种
houses[houseNums-1] = null;
houseNums --;//少一个
3.2 第二种(这种自加加,自减减用很多的,如果要用到自增自减的要想到这个)
houses[--houseNums] = null;
*/
for (int i = index; i < houseNums - 1; i++) {
houses[i] = houses[i + 1];
}
houses[--houseNums] = null;
return true;
}
//findById(),返回House对象或者null
public House findById(int findId) {
/*
findId和已有数据的id进行匹配,若匹配上则输出信息
一定注意是和数组元素的id比较而不是和数组元素的下标比较!!!
如果找到就返回这个house对象,如果没找到则返回空
(比我那个返回当前下标然后使用get方法获取house对象的方法好)
*/
for (int i = 0; i < houseNums; i++) {
if (findId == houses[i].getId()) {
return houses[i];
}
}
return null;
}
}