集合如何区分对象
How do sets differentiate between objects?
一个集合如何区分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?
Java
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?
在C++中,集合依赖于运算符<()是为类A定义的,或者您提供了一个为集合提供严格弱排序的比较对象。
对于Java
,它取决于equals, hashcode
合同。
对于Java部分,负责确定两个物体是否相等的方法是:
public boolean equals(Object other)
不要与混淆
public int hashCode()
其合约规定两个相等的对象必须返回相同的数字,但返回相同数字的两个对象可能相等,但不一定相等。
equals方法的默认实现是按内存地址相等,因此,如果类A没有重写equals方法,则contains方法将返回false。
若要使set.contents(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方法决定了两个对象之间的相等性,但所使用的集合实现中的一些初步步骤(例如HashSet或TreeSet)可能会依赖于其他东西:
例如,HashSet使用hashCode()函数来查找项可能所在的内部位置,因此,如果A没有重写/正确实现hashCode(。
为了让TreeSet内部实现正确地找到其中的项,所包含的项必须正确地实现Comparable接口,或者TreeSet本身必须提供正确实现的Comparator实例。
对于C++,根据集合::插入C++引用
由于集合容器不允许重复值每个的插入操作检查插入的元素是否为另一个元素已存在于具有相同值的容器,如果是,元素未插入,并且-如果该函数返回一个值迭代器返回
它们检查值,不像Java那样只检查地址。
至少在Java中,比较是在哈希代码上进行的,默认情况下,哈希代码是从对象在内存中的位置创建的。因此,在问题的Java部分,aset.contains(a2);
将返回false,因为a2
指向与a
不同的内存部分。
恐怕我不能评论C++是如何工作的!
Java调用对象的equals
方法,如果您没有重写它,那么它与调用Object.hashCode()
相同。
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- const auto & 和 auto & if reference 对象之间的区别是 const
- 将QML数组和MAP/对象类型与C 区分开
- 为什么免费存储区中对象的生存期绑定到范围
- 对象文件"Version References"从何而来?
- 对象Mat(args)之间的区别是什么——内存分配明智;Object*Mat=新Mat(args);在C++中
- 这些对象初始化之间的区别是什么
- 动态对象数组在C++和Java中有何不同?
- 在没有 new 关键字的情况下初始化C++对象的内存从何而来
- 字符串流对象()和对象之间的区别是什么
- 多暗对象的多暗阵列和仅包含一个暗对象的一个较高暗的阵列之间的区别是什么
- 缺少复制构造函数与对象切片有何关系
- 返回对象的两种形式的区别是什么?
- 创建引用和创建对象的主要区别是什么?