3

我很惊讶地看到 equals() 显然被ArrayList<String>. 因为 Collection<> 中的 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
4

3 回答 3

4

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

有一些先例——参见例如TreeSet使用基于比较的相等的实现,以及IdentityHashSet使用引用相等的实现——但这些通常只应在相等的两个概念匹配时使用,或者用于重要且不寻常的需要。

于 2013-01-03T01:56:57.100 回答
4

列表的 Javdaocs是你的朋友。List.contains()依赖于.equals()

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

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

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

于 2013-01-03T01:57:45.300 回答
0

你可以试试 System.out.println(sb.toString().equals("Bush")); 在你的课堂上,看看它会返回什么。它将返回 true。所以在第二种情况下它返回/打印真实。

于 2013-01-03T04:11:35.287 回答