【问题标题】:Finding and replacing elements in Linked List查找和替换链表中的元素
【发布时间】:2012-03-14 06:53:37
【问题描述】:

我需要能够在链接列表中搜索某些唯一元素(用户名、密码、电子邮件),在找到这些元素后,我需要转到列表中的下一个节点并开始一系列允许用户更改的语句档案信息。出于某种原因,我的代码不起作用,我不知道如何修复它。任何帮助都会很棒!

GUI 的外观

帐号类链接: http://pastebin.com/jnBrcnP1

所以用户填写必填信息,如果他们想更改个人资料信息,例如“姓名”或“性别”,他们会更改信息,然后将旁边的组合框设置为“是”,然后单击按钮“保存设置” ”。

链接列表如下所示:

tobi
tobi123
tobi@hotmail.com
tobi
Mixed Breed
Male
1-2
Virginia
Walking
peppy
peppy123
peppy@hotmail.com
peppy
Chihuahua
Male
5-6
Virginia
Eating

这是我的按钮代码:

private void jButtonP1ActionPerformed(java.awt.event.ActionEvent evt) {                                          
    //New Linked List created from file
    LinkedList<Account> account = new LinkedList<Account>();

    try
    {
        read(account, "doggydates.txt");
    } catch (Exception e)
    {
        System.err.println(e.toString());
    }
        display(account);

    //user information
    String username = jTextFieldP3.getText();
    String password = jPasswordFieldP1.getText();
    String email = jTextFieldP4.getText();
    String name = jTextFieldP1.getText();
    String breed = (String) jComboBoxP4.getSelectedItem();
    String gender = (String) jComboBoxP3.getSelectedItem();
    String age = (String) jComboBoxP1.getSelectedItem();
    String state = (String) jComboBoxP2.getSelectedItem();
    String hobby = jTextFieldP2.getText();
    //change combo boxes
    String passchange = (String) jComboBoxP13.getSelectedItem();
    String emailchange = (String) jComboBoxP14.getSelectedItem();
    String namechange = (String) jComboBoxP6.getSelectedItem();
    String breedchange = (String) jComboBoxP7.getSelectedItem();
    String genderchange = (String) jComboBoxP8.getSelectedItem();
    String agechange = (String) jComboBoxP9.getSelectedItem();
    String statechange = (String) jComboBoxP10.getSelectedItem();
    String hobbychange = (String) jComboBoxP11.getSelectedItem();

    //cancel combo box
    String accountcancel = (String) jComboBoxP5.getSelectedItem();

    if(username.equals("") || password.equals("") || email.equals("")) // If password and username is empty > Do this >>>
    {
        jButtonP1.setEnabled(false);
        jTextFieldP3.setText("");
        jPasswordFieldP1.setText("");
        jTextFieldP4.setText("");
        jButtonP1.setEnabled(true);
        this.setVisible(true);
    }
    else
    {
        ListIterator<Account> itr = account.listIterator();
        while (itr.hasNext()) 
        {
            Account item = itr.next();
            if(item.getUsername().equals(username) && item.getPassword().equals(password))
            {

                if(passchange.equals("Yes"))
                {    
                    for(Account acc : account){
                        if(acc.getUsername().equals(username)){
                            acc.goToNext();
                            acc.setDataAtCurrent(password);
                        }
                    }
                }

                if(emailchange.equals("Yes"))
                {    
                    for(Account acc : account){
                        if(acc.getUsername().equals(username)){
                            acc.goToNext();
                            acc.goToNext();
                            acc.setDataAtCurrent(email);
                        }
                    }
                }

                if(namechange.equals("Yes"))
                {    
                    for(Account acc : account){
                        if(acc.getUsername().equals(username)){
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.setDataAtCurrent(name);
                        }
                    }
                }

                if(breedchange.equals("Yes"))
                {    
                    for(Account acc : account){
                        if(acc.getUsername().equals(username)){
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.setDataAtCurrent(breed);
                        }
                    }
                }

                if(genderchange.equals("Yes"))
                {    
                    for(Account acc : account){
                        if(acc.getUsername().equals(username)){
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.setDataAtCurrent(gender);
                        }
                    }
                }

                if(agechange.equals("Yes"))
                {    
                    for(Account acc : account){
                        if(acc.getUsername().equals(username)){
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.setDataAtCurrent(age);
                        }
                    }
                }

                if(statechange.equals("Yes"))
                {    
                    for(Account acc : account){
                        if(acc.getUsername().equals(username)){
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.setDataAtCurrent(state);
                        }
                    }
                }

                if(hobbychange.equals("Yes"))
                {    
                    for(Account acc : account){
                        if(acc.getUsername().equals(username)){
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.goToNext();
                            acc.setDataAtCurrent(hobby);
                        }
                    }
                }                    

                if(accountcancel.equals("Yes"))
                {    
                    for(Account acc : account){
                        if(acc.getUsername().equals(username)){
                            acc.deleteCurrentNode();
                            acc.goToNext();
                            acc.deleteCurrentNode();
                            acc.goToNext();
                            acc.deleteCurrentNode();
                            acc.goToNext();
                            acc.deleteCurrentNode();
                            acc.goToNext();
                            acc.deleteCurrentNode();
                            acc.goToNext();
                            acc.deleteCurrentNode();
                            acc.goToNext();
                            acc.deleteCurrentNode();
                            acc.goToNext();
                            acc.deleteCurrentNode();
                            acc.goToNext();
                            acc.deleteCurrentNode();
                        }
                    }
                }  

            }
        }

        String file_name = "doggydates.txt";
        try {
                FileWriter fstream = new FileWriter(file_name);
                BufferedWriter out = new BufferedWriter(fstream);

                ListIterator itr2 = account.listIterator();
                while (itr2.hasNext()) {
                    Account element = (Account) itr2.next();
                    out.write("" + element);
                    out.newLine();
                }
                out.close();
                System.out.println("File created successfully.");

        } catch (Exception e) {
        }

    }
}                                         

读取方法:

public static void read(LinkedList<Account> account, String inputFileName) throws java.io.IOException{
    BufferedReader infile = new BufferedReader(new FileReader(inputFileName));
    while(infile.ready())
    {        
    String username = readLine(infile);
    String password = readLine(infile);
    String email = readLine(infile);
    String name = readLine(infile);
    String breed = readLine(infile);
    String gender = readLine(infile);
    String age = readLine(infile);
    String state = readLine(infile);
    String hobby = readLine(infile);

    Account a = new Account(username, password, email, name, breed, gender, age, state, hobby);
    account.add(a);
    a.showList();
    }
    infile.close();
}

【问题讨论】:

  • 您为什么要两次搜索同一个帐户?您已经通过迭代器获得了正确的对象。
  • 您的评论显示“如果密码 AND 用户名为空 > 执行此操作”,但您的代码显示“如果密码 OR 用户名 OR 电子邮件为空..."
  • 我可能有误会,但这里的列表似乎不是正确的结构......也许是地图?

标签: java linked-list


【解决方案1】:

查看您的代码,您可以这样做:

首先,LinkedList&lt;Account&gt; account = new LinkedList&lt;Account&gt;(); 这意味着每次用户单击保存设置按钮时,您都会创建列表。

第二,ListIterator&lt;Account&gt; itr = account.listIterator();,但帐户是一个空列表!因此,您无法将任何单个对象与您的任何人员数据进行比较。

最后但同样重要的是,read(account, "doggydates.txt"); 在完成所有比较之后,我猜您正在读取文件数据并填写您的列表。

重新组织您的代码,然后重试。

更新: 在查看了您的所有代码后,我发现您的设计存在一些问题:

  1. Account 类是您的实体。这个类必须有你的列表的数据。您可以像 LinkedList 的 Node 一样重用这个类,指定指向其他 Account 对象引用的指针,无需使用 ListNode 实例。
  2. 要实现 LinkedList,您将使用 Account 类。但这是在LinkedList&lt;Account&gt; 内,所以你有一个LinkedList 的LinkedList。我猜你不希望这种行为。

您可以将设计更改为更简单的东西。我会给你 2 个样品供你设计:

表格 1. 使用您的 Acount 类作为 LinkedList 节点。

public class Account {

    private Account next;
    private Account previous;
    private String username;
    private String password;
    private String email;
    private String name;
    private String breed;
    private String gender;
    private String age;
    private String state;
    private String hobby;

    //constructor logic...

    //getters and setters...

    //toString method (for System.out.println)
}

public class AccountLinkedList {
    private Account head;
    private int size;
    public AccountLinkedList() {
        this.size = 0;
        this.head = null;
    }
    public boolean insert(Account account) {
        if (this.head == null) {
            this.head = account;
        } else {
            Account current = head;
            while (current.getNext() != null) {
                current = current.getNext();
            }
            //maintain the LinkedList order
            current.setNext(account);
            account.setPrevious(current);
        }
    }
    public Account findAccount(Account account) {
        Account current = head;
        while (current != null) {
            if (current.equals(account) {
                return current;
            }
            current = current.getNext();
        }
        return null;
    }
    //create the other methods to search, delete and traverse your list...
}

public class MyProgram {
    public void jButtonP1ActionPerformed(java.awt.event.ActionEvent evt) {
        Account account = new Account();
        //set the account data, I'll just stick to username and
        //password attributes
        String username = jTextFieldP3.getText();
        String password = jPasswordFieldP1.getText();
        account.setUsername(username);
        account.setPassword(password);
        //perform the update
        updateData();
    }
    public void updateData(Account account) {
        AccountLinkedList accountList = new AccountLinkedList;
        //loading data into our list
        loadDataFromFile(accountList, "myFile.txt");
        //perform the search operation
        Account accountAux = accountList.findAccount(account);
        //if the account is found, then update the accountAux data
        if (accountAux != null) {
            updateAccountData(accountAux, account);
        } else {
            accountList.insert(account);
        }
        //saving the modified data
        saveDataToFile(accountList, "myFile.txt");
    }
}

Form 2. 像实体一样使用Account类,使用Java LinkedList实现:

//check that now you don't have the next and previous attributes
public class Account {

    private String username;
    private String password;
    private String email;
    private String name;
    private String breed;
    private String gender;
    private String age;
    private String state;
    private String hobby;

    //constructor logic...

    //getters and setters...

    //toString method (for System.out.println)
}

public class MyProgram {
    public void jButtonP1ActionPerformed(java.awt.event.ActionEvent evt) {
        Account account = new Account();
        //set the account data, I'll just stick to username and
        //password attributes
        String username = jTextFieldP3.getText();
        String password = jPasswordFieldP1.getText();
        account.setUsername(username);
        account.setPassword(password);
        //perform the update
        updateData();
    }
    public void updateData(Account account) {
        LinkedList<Account> accountList = new LinkedList<Account>();
        //loading data into our list
        loadDataFromFile(accountList, "myFile.txt");
        //perform the search operation
        ListIterator<Account> li = accountList.listIterator();
        Account accountAux = null;
        while(li.hasNext()) {
            accountAux = li.next();
            //matching the account data outside with the current account
            //of the list iterator, this is just a sample, you can change
            //this logic
            if (accountAux.equals(account) {
                updateAccountData(accountAux, account);
                break;
            }
            accountAux = null;
        }
        //in case the account was not fount in the LinkedList, add it.
        if (accountAux == null)
            accountList.add(account);
        //saving the modified data
        saveDataToFile(accountList, "myFile.txt");
    }
}

IMO,我会坚持使用 Form 2 而不是 Form1。希望对你有帮助。

【讨论】:

  • 好的,所以我在创建列表后立即移动了用于读取文件的代码,但我仍然收到使用空列表进行迭代的错误。
  • @GeorgeKingoftheZombiesSpeach 你检查过你的read(account, "doggydates.txt"); 确实有效吗?你做过测试吗?也许 doggydates.txt 不是包含您数据的文件,或者 doggydates.txt 是空的。
  • 是的,在它给出尝试迭代空列表的错误之前,它会正确显示链接列表。它从文件中正确读取数据并正确保存。
  • @GeorgeKingoftheZombiesSpeach 你能更新你的jButtonP1ActionPerformed 方法代码吗?
  • 完成了,我所做的只是将文件代码移动到链表的创建下。还是什么都没有
【解决方案2】:

我建议您重新考虑您的设计。我看到您正在混淆 Account Class 中参数的链接 lsit 的概念和 Account 实例的链接列表。

您可能需要的选项: 您有一个帐户的链接列表,例如,链接列表应该有两个 Account 对象。

LinkedList<Account> accounts = new LinkedList<Account>();
load(accounts, file);

应该有两个对象 {tobiaccount, peppyaccount} 你需要在这里写一个加载函数,这是另一个问题。

然后,如果这确实是您想要的,每个帐户都可能有自己的参数链接列表。

然后您将有一个链接列表(帐户)的链接列表

{
   {tobi, tobi123, tobi@hotmail.com, tobi, Mixed Breed, Male, 1-2, Virginia, Walking},
   {peppy, peppy123, peppy@hotmail.com, peppy, Chihuahua, Male, 5-6, Virginia, Eating}
}

如果您想这样做,您应该考虑简化您的 Account 类并确保其中的列表正确填充。

然而,这仍然不是一个好的设计,除非你正在做一个关于链表的奇怪作业。

最佳设计是使用单个链表,而不是嵌套链表;将 Accounts 放在一个链表上,并通过 Account 类中已有的 set/get 方法访问每个参数。

【讨论】:

  • 好吧,老实说,我知道我的帐户类搞砸了,我还没有时间修复它。基本上我一直在从许多不同的来源寻找建议,所以我很困惑。我知道使用类型 Account 创建一个链表意味着它是一个对象的链表。我认为只做一个字符串的链接列表会更好,但我只是在使用我所拥有的
  • 我只需要知道如何修复我的迭代器,以便正确找到值。现在我的迭代器没有返回任何东西,因为列表是空的。运行后我会优化一切。
  • 好的,让我们继续使用这里的内容。最大的问题是当您尝试迭代它时,您要迭代的“帐户”是空的。你要通过调用 read() 来填充它吗? read() 函数是什么样的?
  • 您的链接列表将是一个字符串列表,而不是帐户。这使您的帐户类对您想要的东西毫无用处。
  • 是的,它使用 read 方法从文件中读取行,然后创建一个新的帐户对象,将它们添加到帐户对象中,然后将它们添加到链表中。
猜你喜欢
  • 2011-02-04
  • 1970-01-01
  • 2019-02-20
  • 2018-08-18
  • 2018-08-05
  • 2017-10-01
  • 1970-01-01
  • 2015-09-06
  • 1970-01-01
相关资源
最近更新 更多