2015-02-24 284 views
1

我有一个for循环,用于比较用户登录详细信息以启动应用程序的下一个屏幕。如何在for循环中只执行一次else块

如果用户输入的字段与从数据库返回的ArrayList中的数据成功匹配,程序将启动下一个屏幕 - 如果它们不匹配,则使用JOptionPane将错误消息输出给用户。

我的问题是错误消息是为for循环的每次迭代输出的,但我希望消息只显示一次。

//if name or password are NOT left blank proceed with the check otherwise output error message in the text area 
    if (!name.equals("") && !password.equals("")) { 
     for (int i = 0; i < passwords.size(); i++) { 
      if (name.equals(userNames.get(i)) && (password.equals(passwords.get(i)))) { 
       myHomeGUI.setVisible(true); 
       break; 
      } else { 
       JOptionPane.showMessageDialog(null,"Sorry, no user recognized with those credentials\nPlease try again"); 
      } 
     }//end for loop 
    } else { 
     JOptionPane.showMessageDialog(null,"Sorry, no fields can be left blank"); 
    }//end 
+2

因此,在消息后添加一个break语句; – OldProgrammer 2015-02-24 12:32:13

+0

试过,如果我有一个休息声明后消息在其它它不会工作。例如,如果我的arraylist for userNames的第三个位置是david,并且用户输入了不在数组列表中的john,它将跳出循环,并且永远不会达到大卫,因此永远不会评估为True – RoRo88 2015-02-24 12:34:43

+0

我会认为关于更改userNames /密码的事情。为什么你有两个列表? (例如)带有用户名/密码的(Hash)Map 会更好吗?那么你不需要经过一个循环。只是比较密码与map.get(用户名) – griFlo 2015-02-24 12:35:45

回答

5

这是发生,因为你把你的loopelse condtion这在每Iteration

执行试试这个:

boolean isValid=false; 
for (int i = 0; i < passwords.size(); i++) { 
      if (name.equals(userNames.get(i)) && (password.equals(passwords.get(i)))) { 
       myHomeGUI.setVisible(true); 
       isValid=true; 
       break; 
      } 
}//end for loop 
if(!isValid) { 
JOptionPane.showMessageDialog(null,"Sorry, no user recognized with those credentials\nPlease try again"); 
} 

更新

由于@Joelblade建议,你也可以将此身份验证逻辑转换为sepera TE法

public boolean isAuthenticationPassed(String userName,String password){ 
       return true; // When Login Successfull 
       or 
       return false; // When Login unsuccessfull 
    } 

然后检查你的LoginController

if(isAuthenticationPassed){ 
    // Do whatever you want to do 
} 
else{ 
//Return to Login Page with error/or show Dialog Box 
} 
+0

这几乎是我会使用的结构。你甚至可以将整个for循环移动到一个方法中(boolean authenticateUser(name,password)),并执行:if(!authenticateUser(name,password)) – Joeblade 2015-02-24 12:42:05

+0

@Joeblade,我是模块化方法的大力支持者,所以没有提供太多的建议。在我的回答中加入这个建议:) – 2015-02-24 12:45:07

0

正如评论上面说:你也可以使用一个地图,而不是两个列表

Map<String,String> map = new HashMap<String,String>(); 
    map.put("john", "1234"); 
    map.put("test", "asdf"); 

    String name = "test"; 
    String password = "asdf"; 


    //if name or password are NOT left blank proceed with the check otherwise output error message in the text area 
    if (!name.equals("") && !password.equals("")) { 

      if(map.get(name)!=null && map.get(name).equals(password)) 
       myHomeGUI.setVisible(true); 
       break; 
      } else { 
       JOptionPane.showMessageDialog(null,"Sorry, no user recognized with those credentials\nPlease try again"); 
      }   
    } else { 
     JOptionPane.showMessageDialog(null,"Sorry, no fields can be left blank"); 

    }//end 
+0

在源代码中,不应该暴露像这样的密码(或其他机密/敏感信息)。这是不好的做法 – 2015-02-24 12:47:57

+0

你当然是绝对正确的! RoRo88之前没有使用Map,所以我只是想让他展示如何插入数据。 – griFlo 2015-02-24 12:53:19

0

如果你重构你的代码了到更多的逻辑部分,它将更容易编码和理解,例如:

if (name.equals("") || password.equals("")) { 
    JOptionPane.showMessageDialog(null,"Sorry, no fields can be left blank"); 
} else if(doesUserExist(name, password)) { 
    myHomeGUI.setVisible(true); 
} else { 
    JOptionPane.showMessageDialog(null,"Sorry, no user recognized with those credentials\nPlease try again"); 
} 

// ... new method 

private boolean doesUserExist(String name, String password) { 
    for (int i = 0; i < passwords.size(); i++) { 
     if (name.equals(userNames.get(i)) && (password.equals(passwords.get(i)))) { 
      return true; 
     } 
    } 
    return false; 
}