Home » Java » set does not contain an item that equals one of its members?

set does not contain an item that equals one of its members?

Posted by: admin December 28, 2021 Leave a comment


So according to the Java API, Set::contains

returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e))

So … why is it this method returns false even IF the set contains exactly one element that is equal to creds?

private boolean validate(Credentials creds){
    Set<Credentials> acceptedUsers = getAcceptedUsers();
    return acceptedUsers.contains(creds);

More specifically, I inserted some printlns

private boolean validate(Credentials creds){
    Set<Credentials> acceptedUsers = getAcceptedUsers();

    System.out.print("accepted users: ");
    System.out.print("accessing user: ");
    System.out.println("items are equal: " + acceptedUsers.stream().map(c -> c.equals(creds)).collect(Collectors.toSet()));
    System.out.println("access ok: " + (acceptedUsers.contains(creds) ? "YES" : "NO"));

    return acceptedUsers.contains(creds);

and this is what it had to say:

accepted users: [[
accessing user: [
items are equal: [true]
access ok: NO

getAcceptedUsers currently returns a dummy set

private Set<Credentials> getAcceptedUsers(){
    return new HashSet<Credentials>(){{add(new Credentials("foo","bar", false));}};

and Credentials is implemented as

class Credentials{
    final String username;
    final String password;

    public Credentials(String username, String password, boolean isPasswordHashed) {
        this.username = username;

        if(isPasswordHashed) this.password = password;
        else {
            MessageDigest md;
            try {
                md = MessageDigest.getInstance("SHA-256");
            } catch (NoSuchAlgorithmException e) {
                throw new IllegalStateException(e);

            byte[] hash = md.digest();

            this.password = (new HexBinaryAdapter()).marshal(hash);

    public boolean equals(Object obj) {
        if(obj == null) return false;
        if(!(obj instanceof Credentials)) return false;
        Credentials other = (Credentials)obj;
        return this.username.equals(other.username) && this.password.equals(other.password);

    public String toString() {
        return String.format("[\n\t%s\n\t%s\n]", username,password);

Implementing equals method is NOT enough, you must implement hashCode too.

Like you can read here:

Returns the hash code value for this set. The hash code of a set is defined to be the sum of the hash codes of the elements in the set, where the hash code of a null element is defined to be zero. This ensures that s1.equals(s2) implies that s1.hashCode()==s2.hashCode() for any two sets s1 and s2, as required by the general contract of Object.hashCode().


If you want to use a HashMap or a HashSet, you’ll need to override the hashCode() method so that objects that are equal have the same hash code. E.g.:

public int hashCode() {
    return Objects.hash(username, password);