为什么.equals()方法不会覆盖Java中的基元数组?

时间:2018-06-01 13:09:20

标签: java arrays equals language-design

我目前正在开展一个项目,我希望使用用户名和密码与数据库进行比较来实现登录机制。

我有这样的想法:

public boolean verifyUser( String username, char[] password ) 
{
  List<char[]> dbpass = getPasswords( username );
  if ( dbpass.contains( password ) )
  {
    overwriteWithNonsense( password );
    return true;
  }
  overwriteWithNonsense( password );
  return false;
}

当我注意到我的单元测试失败了。所以我深入研究了一下,注意到Object::equals方法没有覆盖基元数组,这解释了为什么List::contains 总是评估为false

我知道有一种可行的解决方法:

if ( dbpass.stream().anyMatch( pw -> Arrays.equals( pw, password ) ) )
{
  overwriteWithNonsense( password );
  return true;
}

我的问题是为什么设计师选择保留Object::equals的“默认实现”?使用静态实用程序方法(如Arrays.equals(array1,array2)

)实现框架会不会更方便

3 个答案:

答案 0 :(得分:6)

"Select Top 1 bc.Tier_Name, bc.Unit_ID, bc.Name, bc.Description_2 " & _ "FROM bc_subs as bc INNER JOIN Product_V as v" & _ "ON v.ABC = " & "ABC: " & "bc.Unit_ID " 的任何Collection s大多是糟糕的设计。它们不应该一起使用。你可能更擅长引入一个微不足道的,但需要array

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 } } 。 (我也缩短了你的List<Password>方法,因为它看起来有点多余):

verifyUser

(关于为什么未被覆盖的其他问题主要是偏离主题的,因为只有java-devs才能真正回答这个问题。)

答案 1 :(得分:4)

在Java中array不是一个类,但是从Java Doc section 4.3.1它被视为一个对象。现在因为这不是一个类,所以equals/hashCode没有代码。

现在,对于比较数组的解决方案,您可以使用Arrays.equals方法比较两个数组:

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

答案 2 :(得分:0)

我认为没有充分的理由。您通常被鼓励使用ArrayList作为一个完整的容器。但是按照equals()实施AbstractList似乎只会有好处。 始终==确定两个引用是否是同一个对象。

Java数组是一个不同寻常的野兽,因为它们可能包含原语,但这似乎并没有太大的障碍。

这些数组是否相等?

Integer objects[]={Integer.valueOf(1),Integer.valueOf(1000)};
int integers[]={1,1000}; 

我选择了&#39; no&#39;最一致的。但如果不是,你将获得这些对象不会相等的潜在惊人语义:

int ai[]={1,2,3}; 
long al[]={1,2,3};

也许没有人真正考虑过它并且改变那些如此基本的东西肯定会产生一些代码破坏的后果。