集如何区分对象?

时间:2011-06-01 07:13:24

标签: java c++ set

如何区分Java和C ++中的对象?或者根本没有区分它们?

以这些为例:
C ++

std::set<A> aset;
A a(1, 2); // Assume A has only two elements, and this constructor sets them both
aset.insert(a);
A a2(1, 2); // This would initialise a `A' object to the same values as `a', but a different object
aset.count(a2); // Would this return 1 or 0?

爪哇

set<A> aset;
A a = new A(1, 2); // Assume A has only two elements, and this constructor sets them both
aset.add(a);
A a2 = new A(1, 2); // This would initialise a `A' object to the same values as `a', but a different object
aset.contains(a2); // Would this return true or false?

6 个答案:

答案 0 :(得分:7)

在C ++中,集合取决于为类A定义的运算符&lt;(),或者您为集合提供strict weak ordering的比较对象。

答案 1 :(得分:4)

对于Java,它取决于equals, hashcode合同。

答案 2 :(得分:1)

对于Java部分, 负责确定两个对象是否相等的方法是:

public boolean equals(Object other)

不要与

混淆
public int hashCode()

谁的合同声明两个等于对象必须返回相同的数字,但返回相同数字的两个对象可能是,但不一定相等。

equals方法的默认实现是内存地址相等,因此如果A类没有覆盖equals方法,则contains方法将返回false。

要使set.contains(a2)方法返回true,必须覆盖equals和hashCode方法以符合:

public boolean equals(Object other) {
  return other instanceof A && ((A) other).elem1 = this.elem1 && ((A) other).elem2 =    this.elem2; 
}
public int hashCode() {
    return elem1 * 31 + elem2;
}

该集合需要hashCode(假设您正在使用HashSet)来识别对象的内部表示中的位置(即在哪里查找)。 如果您感兴趣,请搜索HashSet \ HashMap以了解内部表示。

至于C ++部分,如果我没记错的话,它取决于正确的运算符重载,但我的C ++充其量生锈。

编辑:我注意到你特意询问了套装,所以我会详细说明如何: 虽然equals方法决定了两个对象之间的相等性,但是所使用的set实现中的一些初步步骤(例如HashSet或TreeSet)可能会在一些额外的东西上传递:

例如,HashSet使用hashCode()函数来查找项可能位于的内部位置,因此如果A没有覆盖/正确实现hashCode()函数,则set.contains(a2)可能返回true或者为假(对于默认实现,它是非确定性的 - 取决于内存位置和集合的当前容量)。

要使TreeSet内部实现正确查找其中的项,要么包含的项必须正确实现Comparable接口,要么必须为TreeSet本身提供正确实现的Comparator实例。

答案 3 :(得分:0)

至少在Java中,对哈希码进行了比较,哈希码默认是从内存中对象的位置创建的。因此,在问题的Java部分,aset.contains(a2);将返回false,因为a2指向内存的不同部分a

我恐怕无法评论C ++是如何工作的!

答案 4 :(得分:0)

for C ++,根据C ++参考中的set :: insert

  

因为set容器不允许重复值,所以   插入操作检查每个   元素插入是否另一个   元素已存在于   具有相同值的容器,如果是这样,   元素未插入且-if   该函数返回一个值-a   返回它的迭代器

他们检查值,不像Java,它只检查地址。

答案 5 :(得分:0)

Java调用对象的equals方法,如果你没有覆盖它,则与调用Object.hashCode()相同。