java - set 不包含等于其成员之一的项目?

标签 java set equals contains

所以根据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))

那么...为什么即使集合只包含一个等于 creds 的元素,此方法也会返回 false?

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

更具体地说,我插入了一些printlns

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

    System.out.print("accepted users: ");
    System.out.println(acceptedUsers);
    System.out.print("accessing user: ");
    System.out.println(creds);
    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);
}

这是它不得不说的:

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

getAcceptedUsers 当前返回一个虚拟集

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

Credentials实现为

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);
            }

            md.update(password.getBytes());
            byte[] hash = md.digest();

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

    @Override
    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);
    }

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

最佳答案

实现equals方法是不够的,你还必须实现hashCode

喜欢你可以阅读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().

关于java - set 不包含等于其成员之一的项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53858966/

相关文章:

java - 启动tomcat时验证eclipse中的jar文件错误

java - 即使线程被声明为 null JAVA,线程仍继续运行

java - 是否可以用 Java 编写宏?

MySQL - 更新表并将列值设置为等于当前行值减去上一行值的差值

java - Java中如何重写equals方法

c++ - 为什么用于字符串比较的 == 运算符相对于任一字符串长度是线性时间(看起来)?

java - JFreeChart:自定义 BoxAndWhisker 图表

objective-c - 返回所有其所有数字都不在任何其他集合中的集合

swift - 如何检查 Swift 中的两组是否相同?

java - 为什么Java的 `equals()`默认不做深度比较