contains()按值比较,而不是引用?

时间:2013-01-03 01:47:19

标签: java

我很惊讶地发现ArrayList<String>显然已经覆盖了equals()。因为Collection&lt;&gt;中的contains()显然比较值,而不是参考。当然,对于Collection<Object>,将比较引用。在下面的程序中,我不应该在第二行上弄错?

public static void main(String[] args) {
    ArrayList<String> al = new ArrayList<String>();
    al.add("Obama");
    al.add("Reagan");
    al.add("Bush");
    al.add("Nyquist");
    StringBuffer sb = new StringBuffer();
    sb.append("Bush");

    System.out.println("compares values? using constants " + al.contains("Bush"));
    System.out.println("compares values? using local variable " + al.contains(sb.toString()));
}

run:
compares values? using constants true
compares values? using local variable true

3 个答案:

答案 0 :(得分:5)

Javdaocs for List你是朋友吗? List.contains()依赖于.equals()

  

布尔包含(对象o)
  如果此列表包含指定的元素,则返回true。更正式地说,当且仅当此列表包含至少一个元素e时才返回true(o == null?e == null:o.equals(e))。

String.equals()比较String的内容(字符):

  

public boolean equals(Object anObject)
将此字符串与之比较   指定的对象。当且仅当参数为时,结果才为真   not null并且是一个String对象,表示相同的序列   字符作为此对象。

答案 1 :(得分:3)

这正是您应该期望的输出,Collection<Object>也不例外。除非另有说明,否则所有Collection类型都使用.equals(Object),并且不同的实现违反了Collection合同。 (要明确的是,将StringObject向上转换不会改变其equals方法的行为。)

有一些先例 - 见例如使用基于比较的相等性的TreeSet实现和使用引用相等性的IdentityHashSet - 但这些应该通常仅在两个相等概念匹配时使用,或者用于重要和不寻常的需要。

答案 2 :(得分:0)

你可以试试System.out.println(sb.toString()。equals(“Bush”));在你的班级,看看它返回什么。它会返回true。所以在第二种情况下,它返回/打印为真。