2017-04-11 70 views
0

我正在使用advance for循環來遍歷我的數組列表中的所有對象,其中包含2個數據,例如用戶名和密碼。無法檢查在對象數組列表中找不到的變量

其目的是讓用戶編輯信息。首先,我循環使用advance for循環然後,如果arraylist中的對象是用戶想要檢查的對象,則使用條件檢查。下面是我如何實現,

String name = Keyboard.readString("Input login name to edit : "); 

for(Player p : pData) 
    { 
     if(name.equals(p.getLoginName())) 
     { 
      System.out.println("1. Login Name"); 
      System.out.println("2. Password");     
      int option = Keyboard.readInt("Select the option to edit "); 

      switch(option) 
      { 
       case 1 : String newLogin = Keyboard.readString("New Login Name"); 
         p.setLoginName(newLogin); 
         System.out.println("Change successful"); 
         break; 
       case 2 : String newPW = Keyboard.readString("New Password"); 
         p.setPassword(newPW); 
         break; 
        default : System.out.println("Wrong option !"); 
           continue; 
       } 
      } 
     }    

} 

我能夠改變的信息,但我得到了在那裏我不能檢查,如果所輸入的用戶可以在對象ArrayList和我可以找到名稱的問題網絡上的任何代碼都可以找到,但似乎找不到任何代碼。我嘗試使用迭代器,但迭代器不提供這樣的需求。我不能在for循環中放置if條件,因爲如果第一個對象不包含這樣的信息,它將「觸發」。

+1

p.IndexOf(newLogin) –

+0

什麼,我可以從這個得到的是指數,但我不能夠檢查用戶輸入的名稱中的所有對象數組存在名單。 –

+0

我認爲,在這裏,你不能避免遍歷所有的對象來查找名稱是否已經存在。另一個 - 但不是很乾淨 - 的方法可能是將名稱存儲在一些額外的數據結構中。 –

回答

0

如果您想快速查找現有用戶名,最好將您在pData中的內容存儲在不同的結構中。您可以通過pData迭代一次,然後爲Player創建用戶名的HashMap。 HashMap中。

0

在過去,當我需要找到某種特定類型的名稱可以通過名稱以字符串的形式(在您的情況下,這是登錄名)時,我使用了一個我開發的類背部。我稱它爲一個庫,使用它不僅可以最大化您的代碼,還可以解決您的問題。

我沒有包括我的庫類的完整代碼,只有你需要使用的部分。隨意使用它:

import java.util.ArrayList; 

public class Library<E> { 
    ArrayList<E> data = new ArrayList<E>(); 
    ArrayList<String> name = new ArrayList<String>(); 

    public int size() { 
     return data.size(); 
    } 

    public boolean contains(String n) { 
     return name.contains(n); 
    }   

    public int indexOf(String name) { 
     return name.indexOf(name); 
    } 

    public E get(String n) { 
     return data.get(name.indexOf(n)); 
    } 

    //returns the object at index i 
    public E get(int i) { 
     return data.get(i); 
    } 

    public void setName(int i, String n) { 
     name.set(i, n); 
    } 

    public String getName(int i) { 
     return name.get(i); 
    } 

    public void add(String n, E v) { 
     name.add(n); 
     data.add(v); 
    } 
} 

爲了您的使用,您可以將pData替換爲庫,並且您也不需要任何for循環。這將是這個樣子:

Library<Player> pData = new Library<Player>(); 

String name = Keyboard.readString("Input login name to edit : "); 
if(pData.contains(name)) { 
    Player p = pData.get(name); 
    //edit the login name, password, etc. here 
} else { 
    System.out.println("Login name does not exist"); 
} 

這個庫類只是相似,它可以取決於用戶輸入一個ArrayList,您可以使用一個字符串的形式使用名稱引用對象的結構和其他的東西,而不是一個必須硬編碼到你的程序中的集合標識符。

就你而言,用戶想要編輯特定對象的數據。您嘗試這樣做的方式是,用戶鍵入登錄名,然後遍歷Player對象的數組列表,然後查看Player.loginName(或任何您的值)是否與用戶輸入的登錄名匹配。雖然這可行,但當您擴展編程項目時,它會變得非常混亂和不便。它也證明比其他方法效率低。

如果你使用這個庫類,它會讓你的代碼更簡單,更容易管理。不必遍歷數組列表並單獨檢查每個Player對象的值。相反,從一開始就用它們的名字來簡單地索引播放器對象會容易得多並且更加高效。這樣,您不必逐個檢查每個值,而只需引用此庫類,它就會精確地告訴您在哪裏可以找到您需要的特定播放器。

此庫類與庫目錄(因此我給它的名稱)非常相似。在圖書館目錄中,你可以查找你需要的書,它會告訴你在哪裏找到它。現在想象一下,自己走過圖書館,單獨檢查每本書的標題和作者,以便找到您需要的內容。這比單純使用目錄要困難得多,效率也更低。這實際上就是這個Library類爲你完成的。

要實現它,你就不需要改變任何關於播放器之類的東西的代碼。是的,您可能已經在Player對象中定義了登錄名,但這並不一定意味着它不能在第二個地方定義。有時候,有多個地方引用相同的價值甚至是一個好主意。唯一改變的是你如何添加到庫中,而不是ArrayList。您只需要爲對象定義一個名稱。對你來說,這將是這個樣子:

Player p = new Player(); //or whatever you do to construct a player 
//do whatever you do to the Player objects here that you normally would before adding them to the array 
pData.add(p.loginName, p); 

Then when you look for the player you need, simply: 

Player p = pData.get(name); //name being the string input from the user 

此外,當您更改播放器的登錄名,你也必須更新其在庫中的條目(請注意,這只是需要做的時候登錄名稱,密碼和其他數據不會影響庫中的條目)。這應該是這樣的:

//code to change login name of the player 
//please note that oName is the original login name of the player before it was modified, NOT the new login name 
int i = pData.indexOf(oName); //index of the player that was just modified 
pData.setName(i, p.loginName); //p is the Player object 
+0

我已經確實有我存儲所有的getter setter方法,以及一個玩家類作爲變量並將它們用作存儲在數組列表中的對象。所以我對如何將它們整合在一起有點困惑。 –

+0

我想我可以理解爲什麼這可能有點混亂。我可以更新答案。 –