I am currently working on a project where I want to implement a login mechanism using a username and a password that gets compared against a database.
I had something like this in mind:
public boolean verifyUser( String username, char[] password )
{
List<char[]> dbpass = getPasswords( username );
if ( dbpass.contains( password ) )
{
overwriteWithNonsense( password );
return true;
}
overwriteWithNonsense( password );
return false;
}
when I noticed that my unit tests were failing. So I took a deeper look at it an noticed that the Object::equals
method is not overriden for arrays of primitives which explained why List::contains
would always evaluate to false
.
I know there is a possible workaround using:
if ( dbpass.stream().anyMatch( pw -> Arrays.equals( pw, password ) ) )
{
overwriteWithNonsense( password );
return true;
}
My question is why the designer chose to keep the 'default implementation' of Object::equals
? Wouldn't it be way more convenient than implementing a framework with static utility methods like Arrays.equals(array1,array2)
?
Any Collection
s of array
s is mostly bad design. They should not be used together. You're probably better of by introducing a trivial, but needed class
:
public class Password{
private final char[] password;
public Password(char[] password){
this.password = password;
}
@Override
public boolean equals(Object obj){
// equals logic
}
@Override
public int hashCode(){
// hashCode logic
}
}
And then having a List<Password>
. (I also shortened your verifyUser
method because it seemed a bit redundant):
public boolean verifyUser( String username, char[] password ){
List<Password> dbpass = getPasswords(username);
boolean contained = dbpass.contains(new Password(password));
overwriteWithNonsense(password);
return contained;
}
(Your other question regarding the why it is not overriden is mostly off-topic, because only the java-devs could really answer that.)
In Java array
is not a class but from Java Doc section 4.3.1 it is treated as an object. Now as this is not a class there's no code for equals/hashCode
.
Now, for your solution to compare arrays you can use Arrays.equals
method to compare two arrays:
public boolean verifyUser( String username, char[] password )
{
List<char[]> dbpass = getPasswords( username );
for(char[] arr : dbpass)
{
if ( Arrays.equals(arr,password) )
{
overwriteWithNonsense( password );
return true;
}
}
overwriteWithNonsense( password );
return false;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With