2017-04-11 57 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

我想我可以理解为什么这可能有点混乱。我可以更新答案。 –