繁体   English   中英

集合如何区分对象?

[英]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++ 中,该集合取决于为 class A 定义的 operator<(),或者您提供比较 object 为集合提供严格的弱排序

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

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

public boolean equals(Object other)

不要混淆

public int hashCode()

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

equals 方法的默认实现是通过 memory 地址相等,因此如果 class 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)来识别 object 可能在集合的内部表示中的位置(即在哪里寻找它)。 如果您有兴趣,请搜索 HashSet\HashMap 以了解内部表示。

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

编辑:我注意到您特别询问了集合,所以我将详细说明如何:虽然 equals 方法确定两个对象之间的相等性,但使用的集合实现中的一些初步步骤(例如 HashSet 或 TreeSet)可能会继续额外的东西:

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

为了让 TreeSet 内部实现正确地在其中找到项目,所包含的项目必须正确实现 Comparable 接口,或者必须为 TreeSet 本身提供正确实现的 Comparator 实例。

至少在 Java 中,比较是在 hash 代码上完成的,默认情况下,该代码是从 objectCD881269B4357106 中的 objectCD881269B4957106 的位置创建的。 所以在问题的 Java 部分, aset.contains(a2); 将返回 false,因为a2指向 memory 到a的不同部分。

恐怕我无法评论 C++ 的工作原理!

对于 C++,根据 set::insert in C++ 参考

因为集合容器不允许重复值,插入操作会检查每个插入的元素是否在容器中已经存在具有相同值的另一个元素,如果是,则不插入该元素并且 - 如果 function 返回值 - 一个迭代器归还给它

.

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM