集合如何区分对象?

问题描述

| 集合如何区分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,and this constructor sets them both
aset.add(a);
A a2 = new A(1,but a different object
aset.contains(a2); // Would this return true or false?
    

解决方法

        在C ++中,集合取决于为类A定义的operator <(),或者您提供一个比较对象,该对象对集合提供严格的弱排序。     ,        对于
Java
,它取决于
equals,hashcode
合同。     ,        对于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或false(对于默认实现,它是不确定的-取决于内存位置和集合的当前容量)。 为了使TreeSet内部实现能够在其中正确找到项目,所包含的项必须正确实现Comparable接口,或者TreeSet本身必须提供有正确实现的Comparator实例。     ,        对于C ++,根据C ++参考中的set :: insert   由于集合容器不允许重复值,因此   每个插入操作检查   元素是否插入   元素已经存在   具有相同值的容器,如果是这样,   没有插入元素,并且-if   该函数返回一个值-   返回它的迭代器 。 它们检查值,与Java不同,Java只检查地址。     ,        至少在Java中,对哈希码进行比较,默认情况下,哈希码是根据对象在内存中的位置创建的。因此,在问题的Java部分中,
aset.contains(a2);
将返回false,因为
a2
指向内存中与
a
不同的部分。 恐怕我无法评论C ++的工作方式!     ,        Java调用对象的
equals
方法,如果尚未覆盖它,则与调用
Object.hashCode()
相同。