我创建了一个向量集,以避免使用迭代器分配等方式导致垃圾回收问题。 (每次遍历 HashSet 的 values 或 keys 时,都需要为 set 引用和 set 迭代器获取新的/释放空闲的内存)
无论如何,据说 Object.hashCode()
方法是对象的唯一标识符。(64位版本可能会失败?)
但无论如何,它都可以被覆盖,因此不能保证独一无二,也不保证每个对象实例的唯一性。
如果我想创建一个“ObjectSet”,如何为每个对象实例获取保证唯一的 ID?
我刚找到了这个答案:
我创建了一个向量集,以避免使用迭代器分配等方式导致垃圾回收问题。 (每次遍历 HashSet 的 values 或 keys 时,都需要为 set 引用和 set 迭代器获取新的/释放空闲的内存)
无论如何,据说 Object.hashCode()
方法是对象的唯一标识符。(64位版本可能会失败?)
但无论如何,它都可以被覆盖,因此不能保证独一无二,也不保证每个对象实例的唯一性。
如果我想创建一个“ObjectSet”,如何为每个对象实例获取保证唯一的 ID?
我刚找到了这个答案:
最简单的解决方案是向对象添加一个字段。这是最快速和最有效的解决方案,并避免了任何对象无法清理的问题。
abstract Ided {
static final AtomicLong NEXT_ID = new AtomicLong(0);
final long id = NEXT_ID.getAndIncrement();
public long getId() {
return id;
}
}
如果您不能修改类,您可以使用类似于@glowcoder删除的解决方案中的IdentityHashMap。private static final Map<Object, Long> registry = new IdentityHashMap<Object, Long>();
private static long nextId = 0;
public static long idFor(Object o) {
Long l = registry.get(o);
if (l == null)
registry.put(o, l = nextId++);
return l;
}
public static void remove(Object o) {
registry.remove(o);
}
hashCode()
的工作方式。返回的值不一定是唯一的。确切的契约在文档中有详细说明。这并不正确。引用文档的说法:Object.hashCode()方法据说是每个对象的唯一标识符
尽可能地,由类
Object 定义的
hashCode 方法确实为不同的对象返回不同的整数。
java.lang.System.identityHashCode(obj);
可以为你执行此操作。它可以获取身份哈希码,即使提供哈希码的方法已被覆盖。请注意,此方法仅在必要时使用。System.identityHashCode(Object)
不需要为不同的对象生成不同的哈希码(正如其他答案和评论中已经说明的那样)! - siegi
IdentityHashMap
的文档吗? - Jon Skeet