目录
//直接先上源码
//这是用户类User
import java.io.*;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Scanner;
import static java.lang.System.exit;
public class User implements Serializable {
private String name;
private String password;
private int Id;
private int grade;
private int jf;
private String address;
private Double ye;
private static final long serialVersionUID = 42L;
public User() {
}
public User(String name) {
this.name = name;
this.password = "111111";
this.ye = 0.0;
this.grade = 1;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
public int getJf() {
return jf;
}
public void setJf(int jf) {
this.jf = jf;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Double getYe() {
return ye;
}
public void setYe(Double ye) {
this.ye = ye;
}
public static void show() throws IOException, ClassNotFoundException, InterruptedException {//查看个人信息+历史充值记录
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户姓名:");
String name = sc.nextLine();
System.out.println("请输入用户密码:");
String pass = sc.nextLine();
FileInputStream fis = new FileInputStream("用户信息表.txt");
ObjectInputStream ois = null;
ArrayList<User> users = new ArrayList<>();
Thread.sleep(2000);
while (fis.available() > 0) {
ois = new ObjectInputStream(fis);
users = (ArrayList<User>) ois.readObject();
//因为每次插入的集合中就一个元素直接写入文件了,所以获得的集合其实里面就一个元素 直接通过索引[0]也行
// User user = users.get(0); //通过索引遍历
// ListIterator<User> it = users.listIterator();//通过迭代器遍历
// while(it.hasNext()){
//
// }
for (User u : users) {
if (u.getName().equals(name) && u.getPassword().equals(pass)) {
System.out.println("----您所查看的信息如下:----");
System.out.println("用户名: " + u.getName());
System.out.println("密码: " + u.getPassword());
System.out.println("等级: " + u.getGrade());
System.out.println("Id: " + u.getId());
System.out.println("积分:" + u.getJf());
System.out.println("地址:" + u.getAddress());
System.out.println("余额" + u.getYe());
System.out.println("----------------------------");
}
}
}
fis.close();
}
public static void fixPassword() throws IOException, ClassNotFoundException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String name = sc.nextLine();
System.out.println("请输入原密码:");
String pass = sc.nextLine();
FileInputStream fis = new FileInputStream("用户信息表.txt");
ObjectInputStream ois = null;
ArrayList<User> users = new ArrayList<>();
boolean flag = true;
while (fis.available() > 0 && flag == true) {
ois = new ObjectInputStream(fis);
users = (ArrayList<User>) ois.readObject();
for (User u : users) {
if (u.getName().equals(name)) {
if (u.getPassword().equals(pass)) {
System.out.println("请输入新密码:");
String newPass = sc.nextLine();
if (newPass.length() < 8) {
System.out.println("密码格式有误!,长度必须大于8");
} else {
ArrayList<User> arr = new ArrayList<>();
User use = new User(name);
use.setPassword(newPass);
arr.add(use);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("用户信息表.txt", true));
oos.writeObject(arr);
oos.close();
flag=false;
System.out.println("修改成功!");
}
} else {
System.out.println("密码错误!");
}
}
}
}
fis.close();
}
public static void addMoney() throws IOException, ClassNotFoundException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户姓名:");
String name=sc.nextLine();
System.out.println("请输入用户密码:");
String pass=sc.nextLine();
System.out.println("请输入充值的金额: ");
Double money=sc.nextDouble();
FileInputStream fis=new FileInputStream("用户信息表.txt");
ObjectInputStream ois=null;
ObjectInputStream demoOis=null;
ArrayList<User> users = new ArrayList<>();
ArrayList<User> demoUsers = new ArrayList<>();
boolean flag=true;
Double firstMoney=0.0;
while(fis.available()>0&&flag==true) {
ois=new ObjectInputStream(fis);
users=(ArrayList<User>)ois.readObject();
for(User u:users){
if(u.getName().equals(name)&&u.getPassword().equals(pass)){
System.out.println(users.size());
if(money>10) {
while(fis.available()>0){
demoOis=new ObjectInputStream(fis);
demoUsers=(ArrayList<User>)demoOis.readObject();
for(User demoU:demoUsers){
if(demoU.getName().equals(name)&&demoU.getPassword().equals(pass))
{
firstMoney=demoU.getYe();
}
}
}
ArrayList<User> arr=new ArrayList<>();
User use=new User(name);
System.out.println("原有金额: "+firstMoney);
use.setYe(firstMoney+money);
use.setPassword(pass);
arr.add(use);
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("用户信息表.txt",true));
oos.writeObject(arr);
oos.close();
flag=false;
System.out.println("充值成功!");
System.out.println("现有金额:"+(firstMoney+money));
}else {
System.out.println("充值失败! 充值金额必须大于10元");
flag=false;
}
}
}
}
if(flag==true){
System.out.println("用户不存在或密码错误!");
}
fis.close();
}
}
//先总体说下实现思路:
通过ObjectOutputstream/ObjectInputstream操作来实现将用户对象写入到文件中以及从文件中读取出来,这样做便于再次打开idea时之前创建的用户数据依旧还可以访问。
//这是测试类Demo
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Scanner;
import static java.lang.System.exit;
public class Demo {
public static void main(String[] args) throws InterruptedException, IOException, ClassNotFoundException {
Scanner sc = new Scanner(System.in);
while (true){
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("请输入你的选择 ---每次选择后请等待2秒");
System.out.println("---------------------");
int choice=sc.nextInt();
switch (choice){
case 1:
addPerson();
Thread.sleep(2000);//找不到c++中的system("pause")按任意键继续 又不想瞬间退出循环 我就使用了线程中的睡眠
//Thread.sleep(time):单位是毫秒
break;
case 2:
showPerson();
break;
case 3:
FixPass();
Thread.sleep(2000);
break;
case 4:
add();
Thread.sleep(2000);
break;
case 0:
System.out.println("退出成功");
exit(0);
default:
//Thread.sleep(2000);
System.out.println("您输入的选择有误!请重新输入");
}
}
}
private static void addPerson() throws IOException {
Scanner sc=new Scanner(System.in);
System.out.println("请输入您的姓名:");
String name=sc.nextLine();
ArrayList<User> arr=new ArrayList<User>();
User user = new User(name);
arr.add(user);
write(arr);
System.out.println("添加成功!");
System.out.println("您的初始密码为:111111");
}
private static void showPerson() throws IOException, ClassNotFoundException, InterruptedException {
User.show();
}
private static void FixPass() throws IOException, ClassNotFoundException {
User.fixPassword();
}
private static void add() throws IOException, ClassNotFoundException {
User.addMoney();
}
private static void write(ArrayList<User> arr) throws IOException {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("用户信息表.txt",true));
oos.writeObject(arr);
oos.close();
}
}
//先介绍核心部分:添加用户到文件中
//添加用户的操作
private static void addPerson() throws IOException {
Scanner sc=new Scanner(System.in);
System.out.println("请输入您的姓名:");
String name=sc.nextLine();
ArrayList<User> arr=new ArrayList<User>();
User user = new User(name);
arr.add(user);
write(arr);
System.out.println("添加成功!");
System.out.println("您的初始密码为:111111");
}
private static void write(ArrayList<User> arr) throws IOException {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("用户信息表.txt",true));
oos.writeObject(arr);
oos.close();
}
/*
输入新用户的姓名,通过User类中带参构造方法来直接为用户的一些属性赋默认初始值。
然后将用户放到ArrayList<User> arr集合中,然后writeObject(arr)把集合写入到src同目录下"用户信息表.txt"表中,如果文件不存在则会自动创建。 ★因为是写入对象,所以需要相应的序列化操作,以及反序列化操作来读取文件中的数据。在序列化过程中别忘了序列化ID直接final一个最终值。
因为后续需要不断的往文件中写入新的用户对象,所以之间将FileOutoutstream第二个参数设为true 也就是可以对文件追加写入数据
这里我直接把写入新用户封装为一个静态方法 减少后续的代码量
*/
//实现添加用户界面
//接下来分别对User类中的展示个人信息、修改密码、充值进行分析
//展示个人信息(包括历史充值记录)
public static void show() throws IOException, ClassNotFoundException, InterruptedException {//查看个人信息+历史充值记录
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户姓名:");
String name = sc.nextLine();
System.out.println("请输入用户密码:");
String pass = sc.nextLine();
FileInputStream fis = new FileInputStream("用户信息表.txt");
ObjectInputStream ois = null;
ArrayList<User> users = new ArrayList<>();
Thread.sleep(2000);//这里我想的是:不能一下子就出来结果,让用户等2秒再看到结果 后续可
//以通过开通会员来修改等待时间 只需要把参数改下就行
while (fis.available() > 0) {
ois = new ObjectInputStream(fis);
users = (ArrayList<User>) ois.readObject();
//因为每次插入的集合中就一个元素直接写入文件了,所以获得的集合其实里面就一个元素 直接通过索引[0]也行
// User user = users.get(0); //通过索引遍历
// ListIterator<User> it = users.listIterator();//通过迭代器遍历
// while(it.hasNext()){
//
// }
for (User u : users) {
if (u.getName().equals(name) && u.getPassword().equals(pass)) {
System.out.println("----您所查看的信息如下:----");
System.out.println("用户名: " + u.getName());
System.out.println("密码: " + u.getPassword());
System.out.println("等级: " + u.getGrade());
System.out.println("Id: " + u.getId());
System.out.println("积分:" + u.getJf());
System.out.println("地址:" + u.getAddress());
System.out.println("余额" + u.getYe());
System.out.println("----------------------------");
}
}
}
fis.close();
}
//因为我是通过序列化操作写入用户对象,所以在对文件读取的时候只能通过反序列化操作。
//while循环遍历出文件中所有的User对象 其中:fis.available()是用来判断文件是否读到了尾部
/*
因为写入对象是我是将对象放入到ArrayList<User>集合中,所以读取的时候通过强制类型转换将读到了Object对象强制转换为ArrayList<User>类型(我的代码实现的思想其实是每次修改、充值、添加用户操作都会立即生成一个新的User对象,把修改前的对象信息放入到新对象中。以至于就会导致每个ArrayList<User>集合中其实就一个对象)。readObject()读取到的Array List<User>集合中其实就一个元素。所以在对读取到的集合进行遍历就非常方便了。(集合遍历三种方式:①迭代器;②增强for();③数组下标形式)
*/
//这里我是通过增强for遍历,控制读取到的对象的条件:用户名和密码来选择出想要查询的用户
//实现展示个人信息界面
//修改密码操作
public static void fixPassword() throws IOException, ClassNotFoundException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String name = sc.nextLine();
System.out.println("请输入原密码:");
String pass = sc.nextLine();
FileInputStream fis = new FileInputStream("用户信息表.txt");
ObjectInputStream ois = null;
ArrayList<User> users = new ArrayList<>();
boolean flag = true;
while (fis.available() > 0 && flag == true) {
ois = new ObjectInputStream(fis);
users = (ArrayList<User>) ois.readObject();
for (User u : users) {
if (u.getName().equals(name)) {
if (u.getPassword().equals(pass)) {
System.out.println("请输入新密码:");
String newPass = sc.nextLine();
if (newPass.length() < 8) {
System.out.println("密码格式有误!,长度必须大于8");
} else {
ArrayList<User> arr = new ArrayList<>();
User use = new User(name);
use.setPassword(newPass);
arr.add(use);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("用户信息表.txt", true));
oos.writeObject(arr);
oos.close();
flag = false;
System.out.println("修改成功!");
}
} else {
System.out.println("密码错误!");
}
}
}
}
fis.close();
}
//这里需要注意的地方:巧妙利用设置flag来退出while循环。当密码修改成功后直接flag=false 就不用继续往后读取数据了
//每当修改密码成功后,我都会创建一个新用户,然后将新用户再次写入到文件中。这样可以有效的保留修改前的用户信息。
//实现修改密码界面
//充值操作
public static void addMoney() throws IOException, ClassNotFoundException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户姓名:");
String name=sc.nextLine();
System.out.println("请输入用户密码:");
String pass=sc.nextLine();
System.out.println("请输入充值的金额: ");
Double money=sc.nextDouble();
FileInputStream fis=new FileInputStream("用户信息表.txt");
ObjectInputStream ois=null;
ObjectInputStream demoOis=null;
ArrayList<User> users = new ArrayList<>();
ArrayList<User> demoUsers = new ArrayList<>();
boolean flag=true;
Double firstMoney=0.0;
while(fis.available()>0&&flag==true) {
ois=new ObjectInputStream(fis);
users=(ArrayList<User>)ois.readObject();
for(User u:users){
if(u.getName().equals(name)&&u.getPassword().equals(pass)){
System.out.println(users.size());
if(money>10) {
while(fis.available()>0){
demoOis=new ObjectInputStream(fis);
demoUsers=(ArrayList<User>)demoOis.readObject();
for(User demoU:demoUsers){
if(demoU.getName().equals(name)&&demoU.getPassword().equals(pass))
{
firstMoney=demoU.getYe();
}
}
}
ArrayList<User> arr=new ArrayList<>();
User use=new User(name);
System.out.println("原有金额: "+firstMoney);
use.setYe(firstMoney+money);
use.setPassword(pass);
arr.add(use);
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("用户信息表.txt",true));
oos.writeObject(arr);
oos.close();
flag=false;
System.out.println("充值成功!");
System.out.println("现有金额:"+(firstMoney+money));
}else {
System.out.println("充值失败!,充值金额必须大于10元");
//flag=false;
}
}
}
}
if(flag==true){
System.out.println("用户不存在或密码错误!");
}
fis.close();
}
/*
整个类中最复杂的就是充值操作:首先每次充值成功后,我这里依旧是继续创建一个新用户,将用户的姓名和密码覆盖到新用户属性上。但是这时候就需要考虑:如何将余额在上一次充值过后的基础上继续累加。
*/
/*
我这里实现余额累加的操作就是:先提前将对象文件读取一遍,然后依次用用户余额覆盖变量firstMoney的值。当遍历到最后一个指定的用户时(这里文件中的指定用户会有多个,因为每次充值后,都会创建一个新的用户,名字和密码全部都一样,然后依次将其写入到文件中。这也就实现了调取充值记录),就可以得到最后一次充值后的用户余额了,然后再次创建新用户,实现setYe(filrstMoney+money)就可以再次更新多次充值后的最终余额。
*/
//实现充值界面
//充值后再次展示个人信息,附带历史充值记录
//接下来看测试类Demo
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Scanner;
import static java.lang.System.exit;
public class Demo {
public static void main(String[] args) throws InterruptedException, IOException, ClassNotFoundException {
Scanner sc = new Scanner(System.in);
while (true){
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("请输入你的选择 ---每次选择后请等待2秒");
System.out.println("---------------------");
int choice=sc.nextInt();
switch (choice){
case 1:
addPerson();
Thread.sleep(2000);//找不到c++中的system("pause")按任意键继续 又不想瞬间退出循环 我就使用了线程中的睡眠
//Thread.sleep(time):单位是毫秒
break;
case 2:
showPerson();
break;
case 3:
FixPass();
Thread.sleep(2000);
break;
case 4:
add();
Thread.sleep(2000);
break;
case 0:
System.out.println("退出成功");
exit(0);
default:
//Thread.sleep(2000);
System.out.println("您输入的选择有误!请重新输入");
}
}
}
private static void addPerson() throws IOException {
Scanner sc=new Scanner(System.in);
System.out.println("请输入您的姓名:");
String name=sc.nextLine();
ArrayList<User> arr=new ArrayList<User>();
User user = new User(name);
arr.add(user);
write(arr);
System.out.println("添加成功!");
System.out.println("您的初始密码为:111111");
}
private static void showPerson() throws IOException, ClassNotFoundException, InterruptedException {
User.show();
}
private static void FixPass() throws IOException, ClassNotFoundException {
User.fixPassword();
}
private static void add() throws IOException, ClassNotFoundException {
User.addMoney();
}
private static void write(ArrayList<User> arr) throws IOException {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("用户信息表.txt",true));
oos.writeObject(arr);
oos.close();
}
}
//利用while(true)死循环实现用户反复操作。如果选择0 直接exit(0) JVM虚拟机强制退出程序。
//在用户每次选择操作时,因为没有找到类似于c++中的system("pause")按任意键继续操作,我就直接使用了线程中的Thread.sleep(time)操作来让用户等待2秒才显示操作后的结果。其实这样也可以将等待时间调长些,让用户付费然后缩短时间,只需要改个参数即可。
//上述大致介绍了实现思路,实现了一些用户的基本功能,其中肯定会有一些Bug,如果有什么问题可以提问,我会在第一时间回复。