ArrayList的contains()方法始终使用自定义对象返回false

Low*_*ile 1 java contains arraylist

我在使用我的代码时遇到了一些麻烦,我会给你一个简单的例子(虽然它会更复杂一点,这个简单的代码也不能正常工作).

class Sign {

  private String char;
  private Integer freq;

  public Sign(String c) {
  this.char = c; 
  }

  @Override
  public boolean equals(Object o) {

   String check = (String)o;
   return check.equals(this.char);
  }

  @Override
  public int hashCode() {

    int hash = 7;
    hash = 31 * hash + this.char.hashCode();
    return hash;
}

}
Run Code Online (Sandbox Code Playgroud)

我假设为了简单起见,总是会有一个等于equals方法的String.还有一些hashCode()也可以确保contains()方法可以工作,这里是测试本身:

    ArrayList<Sign> queueOfSigns = new ArrayList<>();

    Sign test = new Sign("C");
    String c = "C";
    queueOfSigns.add(test);

    if(queueOfSigns.contains("C"))
        System.out.println("I am here!");
Run Code Online (Sandbox Code Playgroud)

无论如何,这个简单的测试代码在这种情况下总是返回false - 所以"我在这里"消息永远不会出现.我一直在尝试一些不同的方法来处理我的代码,但这是因为这个想法是从String文本中获取单个字符并检查ArrayList中是否已存在单个字符.尽管如此 - 如果没有让这个简单的测试正常工作,我就无法继续前进,所以我想问你 - 我错过了什么.这是我第一次使用equals()和hashCode()方法来使我自己的对象与contains()方法一起正常工作.

T.J*_*der 5

您的equals实施不正确.equals有特定的合同; 该代码试图违反该合同.从文档:

equals方法在非null对象引用上实现等价关系:

  • 它是反身的:对于任何非null参考值x,x.equals(x)应该返回true.
  • 它是对称的:对于任何非null参考值xy,x.equals(y)应该返回true当且仅当y.equals(x)回报true.
  • 它是传递性:对于任何非null参考值x,y以及z,如果x.equals(y)回报率truey.equals(z)回报率true,那么x.equals(z)应该返回true.
  • 它是一致的:对于任何非null引用值x以及一致返回或一致返回的y多次调用,前提是不修改在对象比较中使用的信息.x.equals(y)truefalseequals
  • 对于任何非null参考值x,x.equals(null)应返回false.

没有办法将Sign类的实例创建为equals字符串.

  • @LowProfile - 我根本不会使用`ArrayList`.我使用[`Map`](https://docs.oracle.com/javase/10/docs/api/java/util/Map.html)并使用``char`属性存储`Sign`对象作为关键.然后使用`containsKey`来查明地图是否有对象,或者使用`get`来获取基于键的对象. (3认同)
  • 为了完整性,在这些属性中,OP的`equals()`实现仅表现出传递性.它被打破的地方真的被打破了:它有一种讨厌`ClassCastException和`NullPointerException'的习惯. (2认同)