序列化包含其他 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 添加到 SuperUseradd() 调用),但我敢打赌实际上它不会'它发生了。

此外,我看到你从 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()' 时,它不会调用列表中的对象,因此不会保存任何数据更改。

您需要从列表中找到该用户的现有对象。我建议您将列表换成以用户名为键的地图。