序列化包含其他 ArrayList 对象的 ArrayList 对象的问题
Issues Serializing an ArrayList object containing other ArrayList objects
所以我实际上是在序列化 ArrayList 的 ArrayList,但我 运行 遇到了问题。老实说,我对 Java 还是很陌生,我尝试了很多不同的方法来解决这个问题,并在这个网站上进行了不懈的搜索,但都没有成功。我知道我的措辞可能难以理解或令人困惑,所以我将 post 我的代码放在这里查看。提前为所有代码道歉。 SuperUsers 有一个 LoginInfo 数组列表,PasswordKeeper 有一个 SuperUsers 数组列表,而 SuperUser 数组列表在 PasswordKeeper 中被序列化。但对 LoginInfo arraylist 所做的任何更改都不会保存,我无法弄清楚原因。如果有人可以提供帮助,我将不胜感激。谢谢
public class PasswordKeeper{
private ArrayList<SuperUser> users;
private static Scanner keyboard = new Scanner(System.in);
public PasswordKeeper() {
users = new ArrayList();
}
public void login() {
try {
// reads in SuperUser arraylist
get();
} catch (EOFException a) {
System.out.println("You are the First User!");
} catch (IOException b) {
System.out.println(b);
} catch (ClassNotFoundException c) {
System.out.println(c);
}
boolean loopDisplay = true;
while (loopDisplay) {
existingUser = keyboard.next();
existingPass = keyboard.next();
SuperUser temp = new SuperUser(existingUser, existingPass);
System.out.println();
if (users.contains(temp)) {
// viewing superUser method
temp.display();
//saves after method call is over
try {
System.out.println("Saving.");
save(users);
} catch (IOException e) {
System.out.println(e);
}
}
}
//This happens if there is a new user
if(answer == 2){
SuperUser tempNew = null;
boolean cont = true;
String newUser;
String pass;
while(cont){
newUser = keyboard.nextLine();
System.out.println();
//System.out.println(users.size());
tempNew = new SuperUser(newUser, pass);
if(passValid(pass) == true){
if(makeSure(tempNew) == true){
System.out.println("Login Created!");
tempNew = new SuperUser(newUser, pass);
//actually being added to the arraylist
users.add(tempNew);
cont = false;
}
}
}
//SuperUser.display method
tempNew.display();
try{
System.out.println("Saving.");
save(users);
}catch(IOException e){
System.out.println(e);
}
}
}
}
//makeSure and passValid methods
public boolean makeSure(SuperUser user){
if(users.contains(user)){
return false;
}
return true;
}
public boolean passValid(String pass){
boolean passes = false;
String upper = "(.*[A-Z].*)";
String lower = "(.*[a-z].*)";
String numbers = "(.*[0-9].*)";
String special = "(.*[,~,!,@,#,$,%,^,&,*,(,),-,_,=,+,[,{,],},|,;,:,<,>,/,?].*$)";
if((pass.length()>15) || (pass.length() < 8)){
System.out.println("Entry must contain over 8 characters\n" +
"and less than 15.");
passes = false;
}if(!pass.matches(upper) || !pass.matches(lower)){
System.out.println("Entry must contain at least one uppercase and lowercase");
passes = false;
}if(!pass.matches(numbers)){
System.out.println("Password should contain atleast one number.");
passes = false;
}if(!pass.matches(special)){
System.out.println("Password should contain atleast one special character");
passes = false;
}else{
passes = true;
}
return passes;
//serializable methods
public void save(ArrayList<SuperUser> obj) throws IOException {
File file = new File("userInformation.dat");
FileOutputStream fileOut = new FileOutputStream(file, false);
BufferedOutputStream buffedOutput = new BufferedOutputStream(fileOut);
ObjectOutputStream out = new ObjectOutputStream(buffedOutput);
out.writeObject(obj);
out.close();
fileOut.close();
}
public ArrayList<SuperUser> get() throws IOException, ClassNotFoundException {
FileInputStream fileIn = new FileInputStream("userInformation.dat");
BufferedInputStream buffedInput = new BufferedInputStream(fileIn);
ObjectInputStream in = new ObjectInputStream(buffedInput);
users = (ArrayList<SuperUser>) in.readObject();
in.close();
fileIn.close();
return users;
}
public class SuperUser implements Serializable {
private String userName;
private String password;
private static Scanner keyboard = new Scanner(System.in);
private ArrayList<LoginInfo> info = new ArrayList();
public SuperUser(String name, String pass) {
userName = name;
password = pass;
}
public String getUser() {
return userName;
}
public void display() {
String next = keyboard.next();
//want to add data to LoginInfo arraylist
if (next.equalsIgnoreCase("add")) {
add();
} else if (next.equalsIgnoreCase("delete")) {
delete();
} else if (numberCheck(next)) {
int choice = (int) Integer.parseInt(next) - 1;
edit(choice);
//!!!! this: after doing this i lose whatever data i added
//to the LoginInfo arraylist, right after this the
//SuperUser arraylist gets saved. but the added data to
//loginInfo does not
} else if (next.equalsIgnoreCase("logout")) {
System.out.println(info.size());
}
}
public boolean numberCheck(String in) {
try {
Integer.parseInt(in);
} catch (NumberFormatException e) {
return false;
}
return true;
}
//method to add to the Arraylist
public void add() {
System.out.println("What is the website name?:");
String trash = keyboard.nextLine();
String webName = keyboard.nextLine();
System.out.println("The Username?:");
String webUsername = keyboard.nextLine();
System.out.println("The Password?:");
String webPass = keyboard.nextLine();
info.add(new LoginInfo(webUsername, webPass, webName));
System.out.println(info.size());
//method goes back to display
display();
}
}
}
您有一个名为 users
的列表。一旦您创建了新的 SuperUser
实例 (temp
),您将检查它是否属于此列表(users.contains(temp)
,这当然是错误的 - 它会在哪里出现?)。如果它属于,方法 display
将被调用,这反过来会将 LoginInfo
添加到 SuperUser
(add()
调用),但我敢打赌实际上它不会'它发生了。
此外,我看到你从 users
读取的位置(检查新的 SuperUser
实例是否属于那里),我看到你在哪里覆盖它(在解封期间)但我没有看到添加任何那里的实例,这让我觉得它总是空的。
您确定 SuperUser
的数组列表中包含 LoginInfo
吗?
你的问题就在这里
SuperUser temp = new SuperUser(existingUser, existingPass);
System.out.println();
if (users.contains(temp)) {
// viewing superUser method
temp.display();
您使用用户名和密码创建一个临时对象。
您的 'users.contains()' 方法 returns 正确,因为“.equals()”基于用户名,但是 'temp' 对象与列表中的对象不同。
因此,当您调用 'temp.display()' 时,它不会调用列表中的对象,因此不会保存任何数据更改。
您需要从列表中找到该用户的现有对象。我建议您将列表换成以用户名为键的地图。
所以我实际上是在序列化 ArrayList 的 ArrayList,但我 运行 遇到了问题。老实说,我对 Java 还是很陌生,我尝试了很多不同的方法来解决这个问题,并在这个网站上进行了不懈的搜索,但都没有成功。我知道我的措辞可能难以理解或令人困惑,所以我将 post 我的代码放在这里查看。提前为所有代码道歉。 SuperUsers 有一个 LoginInfo 数组列表,PasswordKeeper 有一个 SuperUsers 数组列表,而 SuperUser 数组列表在 PasswordKeeper 中被序列化。但对 LoginInfo arraylist 所做的任何更改都不会保存,我无法弄清楚原因。如果有人可以提供帮助,我将不胜感激。谢谢
public class PasswordKeeper{
private ArrayList<SuperUser> users;
private static Scanner keyboard = new Scanner(System.in);
public PasswordKeeper() {
users = new ArrayList();
}
public void login() {
try {
// reads in SuperUser arraylist
get();
} catch (EOFException a) {
System.out.println("You are the First User!");
} catch (IOException b) {
System.out.println(b);
} catch (ClassNotFoundException c) {
System.out.println(c);
}
boolean loopDisplay = true;
while (loopDisplay) {
existingUser = keyboard.next();
existingPass = keyboard.next();
SuperUser temp = new SuperUser(existingUser, existingPass);
System.out.println();
if (users.contains(temp)) {
// viewing superUser method
temp.display();
//saves after method call is over
try {
System.out.println("Saving.");
save(users);
} catch (IOException e) {
System.out.println(e);
}
}
}
//This happens if there is a new user
if(answer == 2){
SuperUser tempNew = null;
boolean cont = true;
String newUser;
String pass;
while(cont){
newUser = keyboard.nextLine();
System.out.println();
//System.out.println(users.size());
tempNew = new SuperUser(newUser, pass);
if(passValid(pass) == true){
if(makeSure(tempNew) == true){
System.out.println("Login Created!");
tempNew = new SuperUser(newUser, pass);
//actually being added to the arraylist
users.add(tempNew);
cont = false;
}
}
}
//SuperUser.display method
tempNew.display();
try{
System.out.println("Saving.");
save(users);
}catch(IOException e){
System.out.println(e);
}
}
}
}
//makeSure and passValid methods
public boolean makeSure(SuperUser user){
if(users.contains(user)){
return false;
}
return true;
}
public boolean passValid(String pass){
boolean passes = false;
String upper = "(.*[A-Z].*)";
String lower = "(.*[a-z].*)";
String numbers = "(.*[0-9].*)";
String special = "(.*[,~,!,@,#,$,%,^,&,*,(,),-,_,=,+,[,{,],},|,;,:,<,>,/,?].*$)";
if((pass.length()>15) || (pass.length() < 8)){
System.out.println("Entry must contain over 8 characters\n" +
"and less than 15.");
passes = false;
}if(!pass.matches(upper) || !pass.matches(lower)){
System.out.println("Entry must contain at least one uppercase and lowercase");
passes = false;
}if(!pass.matches(numbers)){
System.out.println("Password should contain atleast one number.");
passes = false;
}if(!pass.matches(special)){
System.out.println("Password should contain atleast one special character");
passes = false;
}else{
passes = true;
}
return passes;
//serializable methods
public void save(ArrayList<SuperUser> obj) throws IOException {
File file = new File("userInformation.dat");
FileOutputStream fileOut = new FileOutputStream(file, false);
BufferedOutputStream buffedOutput = new BufferedOutputStream(fileOut);
ObjectOutputStream out = new ObjectOutputStream(buffedOutput);
out.writeObject(obj);
out.close();
fileOut.close();
}
public ArrayList<SuperUser> get() throws IOException, ClassNotFoundException {
FileInputStream fileIn = new FileInputStream("userInformation.dat");
BufferedInputStream buffedInput = new BufferedInputStream(fileIn);
ObjectInputStream in = new ObjectInputStream(buffedInput);
users = (ArrayList<SuperUser>) in.readObject();
in.close();
fileIn.close();
return users;
}
public class SuperUser implements Serializable {
private String userName;
private String password;
private static Scanner keyboard = new Scanner(System.in);
private ArrayList<LoginInfo> info = new ArrayList();
public SuperUser(String name, String pass) {
userName = name;
password = pass;
}
public String getUser() {
return userName;
}
public void display() {
String next = keyboard.next();
//want to add data to LoginInfo arraylist
if (next.equalsIgnoreCase("add")) {
add();
} else if (next.equalsIgnoreCase("delete")) {
delete();
} else if (numberCheck(next)) {
int choice = (int) Integer.parseInt(next) - 1;
edit(choice);
//!!!! this: after doing this i lose whatever data i added
//to the LoginInfo arraylist, right after this the
//SuperUser arraylist gets saved. but the added data to
//loginInfo does not
} else if (next.equalsIgnoreCase("logout")) {
System.out.println(info.size());
}
}
public boolean numberCheck(String in) {
try {
Integer.parseInt(in);
} catch (NumberFormatException e) {
return false;
}
return true;
}
//method to add to the Arraylist
public void add() {
System.out.println("What is the website name?:");
String trash = keyboard.nextLine();
String webName = keyboard.nextLine();
System.out.println("The Username?:");
String webUsername = keyboard.nextLine();
System.out.println("The Password?:");
String webPass = keyboard.nextLine();
info.add(new LoginInfo(webUsername, webPass, webName));
System.out.println(info.size());
//method goes back to display
display();
}
}
}
您有一个名为 users
的列表。一旦您创建了新的 SuperUser
实例 (temp
),您将检查它是否属于此列表(users.contains(temp)
,这当然是错误的 - 它会在哪里出现?)。如果它属于,方法 display
将被调用,这反过来会将 LoginInfo
添加到 SuperUser
(add()
调用),但我敢打赌实际上它不会'它发生了。
此外,我看到你从 users
读取的位置(检查新的 SuperUser
实例是否属于那里),我看到你在哪里覆盖它(在解封期间)但我没有看到添加任何那里的实例,这让我觉得它总是空的。
您确定 SuperUser
的数组列表中包含 LoginInfo
吗?
你的问题就在这里
SuperUser temp = new SuperUser(existingUser, existingPass);
System.out.println();
if (users.contains(temp)) {
// viewing superUser method
temp.display();
您使用用户名和密码创建一个临时对象。
您的 'users.contains()' 方法 returns 正确,因为“.equals()”基于用户名,但是 'temp' 对象与列表中的对象不同。
因此,当您调用 'temp.display()' 时,它不会调用列表中的对象,因此不会保存任何数据更改。
您需要从列表中找到该用户的现有对象。我建议您将列表换成以用户名为键的地图。