## 需求分析
打开我们手机里的记账本,可以发现主要提供如下几个功能:
1. **添加账目**
2. **删除账目**
3. **修改账目**
4. **查询账目**
5. - 查询所有账目
- 按时间区间查询
- 按账目类型查询
6. **退出记账本**
![](https://www.writebug.com/myres/static/uploads/2021/11/17/93650693d875d14924c5eef95c42d07e.writebug)
## 功能预览及代码实现
### 主菜单
主菜单中,主要用于打印提示我们进行选择,然后根据我们的输入再进入不同的子功能模块中。
- 预览
![](https://www.writebug.com/myres/static/uploads/2021/11/17/add8722cea6a75fd563452753d32065b.writebug)
- 代码实现
代码实现很简单,只需要打印出提示信息即可,之后后续输入以及进入不同子功能模块,我们可以使用 `switch` 来进行选择。
```
package com.cunyu;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
/**
* Created with IntelliJ IDEA.
*
* @author : 村雨
* @version : 1.0
* @project : Java 实战
* @package : com.cunyu
* @className : MainApp
* @createTime : 2021/8/1 7:22
* @email : 747731461@qq.com
* @公众号 : 村雨遥
* @website : https://cunyu1943.github.io
* @description :
*/
public class MainApp {
public static void main(String[] args) {
boolean flag = true;
while (flag) {
System.out.println("----------欢迎使用记账系统--------");
System.out.println("----------【1】添加账务----------");
System.out.println("----------【2】删除账务----------");
System.out.println("----------【3】修改账务----------");
System.out.println("----------【4】查询账务----------");
System.out.println("----------【0】退出-------------");
System.out.println("请输入功能序号【0-4】");
}
System.out.println("退出系统,期待下次见面 ~");
}
}
```
### 添加账目
当我们需要添加一笔新的账目时,此时就可以进入 **添加账目** 子模块,这里的功能主要是根据我们自己输入的 ID、类别、账户、类型、金额、时间以及备注将其添加到我们的总账目列表中进行汇总。
- 预览
![](https://www.writebug.com/myres/static/uploads/2021/11/17/16671ce4e7b0dc6db14e804430f76e40.writebug)添加账目
- 代码实现
要实现添加功能也很简单,根据我们的输入,我们利用账目类的构造函数创建一个对象,然后将其加入总账目列表当中就可以了。
```
public void add(List<Bill> billList, int id, String category, String account, String type, double amount, String time, String desc) {
//创建一个账单对象,然后将其加入列表
Bill bill = new Bill(id, category, account, type, amount, time, desc);
billList.add(bill);
}
```
### 删除账目
假如我们的账目要公开给别人看,而自己有的账目又不想让别人看到,咋办呢?很简单!我们只需要将这笔账目干掉即可!这里我们只要输入我们所要删除的账单 ID,然后将其从总账目列表中删除即可。
- 预览
![](https://www.writebug.com/myres/static/uploads/2021/11/17/be262de46daea8587d574e72785583b3.writebug)
- 代码实现
要删除我们的账目,只需要根据我们输入的账单 id,找到对应 id 的账目,然后将其删除即可,这里之所以没有使用 `remove(index)` 的方式,是因为我们的 id 是自己输入的,这其实是不规则的,如果我们使用 `remove(index)` 的方式,就有可能导致越界的问题。
```
public void del(List<Bill> billList, int id) {
//找到对应 id 的账单,并将其删除
for (Bill bill : billList) {
if (bill.getId() == id) {
billList.remove(bill);
}
}
}
```
### 修改账目
我们偷偷拿了私房钱买了猛男必备显卡(RTX 3090)想趁空了打打游戏,遇到老婆查账时,这时候可不能慌,我们只需要把账单偷梁换柱,改换成其他东西就可以,而且此事神不知鬼不觉,美滋滋呀!
- 预览
![](https://www.writebug.com/myres/static/uploads/2021/11/17/ccd395a9c6c9ea455089d98ab1ea87b1.writebug)修改账目
- 代码实现
利用代码实现也很简单,找到对应 ID 的账单,然后重新输入账单各个细节进行修改即可!
```
public void modify(List<Bill> billList) {
Scanner scanner = new Scanner(System.in);
System.out.println("输入你要修改对应账务的 ID");
int id = scanner.nextInt();
System.out.println("请输入修改后的账务类别");
String category = scanner.next();
System.out.println("请输入修改后的账户");
String account = scanner.next();
System.out.println("请输入修改后的类型(收入/支出)");
String type = scanner.next();
System.out.println("请输入修改后的金额");
double amount = scanner.nextDouble();
System.out.println("请输入修改后的时间");
String time = scanner.next();
System.out.println("请输入修改后的备注");
String description = scanner.next();
//找到对应 id 的账单,然后修改对应信息
for (Bill bill : billList) {
if (bill.getId() == id) {
bill.setCategory(category);
bill.setAmount(amount);
bill.setAccount(account);
bill.setTime(time);
bill.setType(type);
bill.setDesc(description);
}
}
}
```
### 查询账目
查询账目这里,我们又分为 3 个不同的功能,既可以查看所有账单,也可以根据我们所输入的时间区间进行筛选,最后,还能够根据我们的输入查询出收入和支出的详细情况。
#### 查询所有账目
- 预览
![](https://www.writebug.com/myres/static/uploads/2021/11/17/d2d3c50aa5f172754c46bebccf3f102e.writebug)所有账目
- 代码实现
查询所有账单很简单,只需要遍历我们总账单列表即可。
```
public void queryAll(List<Bill> billList) {
System.out.println("ID\t\t类别\t\t\t账户\t\t类型\t\t金额\t\t\t时间\t\t\t\t备注");
for (Bill bill : billList) {
System.out.println(bill.getId() + "\t\t" + bill.getCategory() + "\t\t" + bill.getAccount() + "\t\t" + bill.getType() + "\t\t" + bill.getAmount() + "\t\t" + bill.getTime() + "\t\t" + bill.getDesc());
}
}
```
#### 按时间区间查询
- 预览
![](https://www.writebug.com/myres/static/uploads/2021/11/17/ac588d8c5838a665d87897558979f3b0.writebug)
- 代码实现
按照时间跨度来查询稍微要麻烦一些,这里要处理两个输入,一个是开始时间,一个是结束时间,我们需要将账单的时间和这两个时间进行比较,筛选出介于这两者之间的账单。所以这里要涉及到 `Date` 类,然后就是如何从总账单列表中过滤出满足时间跨度的账单。
```
public void queryByTime(List<Bill> billList, String startTime, String endTime) {
// 时间格式化
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
List<Bill> bills = billList.stream().filter(bill -> {
String tmpTime = bill.getTime();
try {
// 将输入的时间字符串转换为格式化的 Date 类型
Date tmpDate = simpleDateFormat.parse(tmpTime);
Date startDate = simpleDateFormat.parse(startTime);
Date endDate = simpleDateFormat.parse(endTime);
// 将介于开始时间和结束时间的账单进行过滤
if (tmpDate.before(endDate) && tmpDate.after(startDate)) {
return true;
}
} catch (ParseException parseException) {
parseException.printStackTrace();
}
return false;
// 将其转换为列表
}).collect(Collectors.toList());
queryAll(bills);
}
```
#### 按类型查询
- 预览
![](ht