问题
I have this method that checks the username and password of a user before login. Now my for loop checks only the first item, it finds that the first condition, u.getRole().equalsIgnoreCase("recruiter")
is not satisfied for the first item, so instead of going and checking the second item it just breaks and returns null.
Why does this happen?
Here is my method:
public User check(String userName, String password) throws AdException {
try {
begin();
Query q = getSession().createQuery("from User");
ArrayList<User> list = (ArrayList<User>) q.list();
System.out.println("recruiterList is: " + list);
for (User u: list) {
System.out.println("Before if user is: " + u);
if (u.getRole().equalsIgnoreCase("recruiter")) {
System.out.println("userName 1 is :" + u.getUserName());
if (u.getUserName().equalsIgnoreCase(userName) && u.getPassword().equalsIgnoreCase(password))
System.out.println("After if recruiter is: " + u);
System.out.println("userName 2 is :" + u.getUserName());
return u;
}
break;
}
} catch (HibernateException e) {
rollback();
throw new AdException("Unfound " + userName, e);
}
return null;
}
回答1:
for (User u: list) {
if (u.getRole().equalsIgnoreCase("recruiter")) {
//sysout
if (u.getUserName().equalsIgnoreCase(userName) && u.getPassword().equalsIgnoreCase(password))
//2 sysout
return u;
}
break; //here break statement will exit your loop just after first Iteration.
}
so try this code.
for (User u: list) {
if (u.getRole().equalsIgnoreCase("recruiter")) {
//sysout
if (u.getUserName().equalsIgnoreCase(userName) && u.getPassword().equalsIgnoreCase(password)){
//2 sysout
return u;
} else{
//your code if password doesnot matched
}
// continue even if more than one recruiter type User Object are in Database.
}else{
//your code if user Role doesnot matched
}
} //loop will check all element present in that array. and if it's ROLE is matched like "Recuriter" then it will check user and password.
回答2:
You use a break
statement within the loop. This causes the loop to exit.
回答3:
Well it makes sense, since if you succeed you return and if you don't, you break, so it breaks:
for (User u: list) {
System.out.println("Before if user is: " + u);
if (u.getRole().equalsIgnoreCase("recruiter")) {
// code which returns at the end
return u;
}
break;
}
The break;
statement is executed whenever the condition isn't met (otherwise you would return
before you reach it), which is why you always check only the first item.
If you want to check all the items, simply remove the break;
statement from your loop.
回答4:
As has been pointed in the comments, you have only two alternatives in the loop, both make the loop to finish (on return
or on break
) Just take off the break;
statement or change it for a continue;
.
By the way, why don't you select from User where role = 'recruiter'
only? This will make the roundtrip to the database server not to return all users, but only the ones that you are interested in.
回答5:
Your code and logic are wrong. u
doesn't change during an iteration of the for-each
loop, it changes after each iteration. Your println
statements suggest that you believe u
is going to change during the first nested if
statement. Since:
System.out.println("userName 1 is :" + u.getUserName());
and:
System.out.println("userName 2 is :" + u.getUserName());
appear in the same if
block, nested in the for-each
loop:
if (u.getRole().equalsIgnoreCase("recruiter")) {
System.out.println("userName 1 is :" + u.getUserName());
if (u.getUserName().equalsIgnoreCase(userName) && u.getPassword().equalsIgnoreCase(password))
System.out.println("After if recruiter is: " + u);
System.out.println("userName 2 is :" + u.getUserName());
return u;
}
You also don't need to use a break
or continue
statement. You don't need a break
statement because you have a return
statement. You don't need a continue
statement because that's what a loop does.
Note also that an if
statement with no curly braces ({ ... }
) only executes the line directly below it. For instance:
if (u.getUserName().equalsIgnoreCase(userName) && u.getPassword().equalsIgnoreCase(password))
System.out.println("After if recruiter is: " + u);
Your code should resemble:
public User check(String userName, String password) throws AdException {
try {
begin();
Query q = getSession().createQuery("from User");
ArrayList<User> list = (ArrayList<User>) q.list();
System.out.println("recruiterList is: " + list);
for (User u: list) {
System.out.println("Before if user is: " + u);
if (u.getRole().equalsIgnoreCase("recruiter")) {
System.out.println("userName 1 is :" + u.getUserName());
if (u.getUserName().equalsIgnoreCase(userName) && u.getPassword().equalsIgnoreCase(password)) {
System.out.println("After if recruiter is: " + u);
// System.out.println("userName 2 is :" + u.getUserName());
return u;
}
}
}
} catch (HibernateException e) {
rollback();
throw new AdException("Unfound " + userName, e);
}
return null;
}
If you want to have a println
statement that outputs what the current username's index is, then don't use a for-each
use a regular for
loop. For instance:
public User check(String userName, String password) throws AdException {
try {
begin();
Query q = getSession().createQuery("from User");
ArrayList<User> list = (ArrayList<User>) q.list();
System.out.println("recruiterList is: " + list);
for (int i = 0; i < list.length; i++) {
System.out.println("Before if user is: " + u);
if (u.getRole().equalsIgnoreCase("recruiter")) {
System.out.println("userName " + (i + 1) + " is :" + u.getUserName());
if (u.getUserName().equalsIgnoreCase(userName) && u.getPassword().equalsIgnoreCase(password)) {
System.out.println("After if recruiter is: " + u);
return u;
}
}
}
} catch (HibernateException e) {
rollback();
throw new AdException("Unfound " + userName, e);
}
return null;
}
来源:https://stackoverflow.com/questions/36832340/why-does-my-for-loop-check-only-the-first-element