Java中的实例集合是什么?

6
Java定义了一个名为Set的接口,其中contains()的定义如下:

如果此集合包含指定元素,则返回true。更正式地说,当且仅当此集合包含一个元素e,使得(o==null ? e==null : o.equals(e))时才返回true

Collection接口将contains()定义如下:

如果此集合包含指定元素,则返回true。更正式地说,当且仅当此集合包含至少一个元素e,使得(o==null ? e==null : o.equals(e))时才返回true

我需要一个Java“实例集”,其中contains()基于==而不是equals()。换句话说,这是一组硬实例,其中两个不同的对象A和B可以共存于同一集合中,因为A!= B
在Java或某些公共库中是否提供了这样的“实例集”?我找不到任何东西,但也许有人在SO上知道得更好。如果没有,我会自己实现。谢谢。
2个回答

13

JRE中没有直接的"实例集"。

但是有一个IdentityHashMap,根据您的术语实现了"实例映射"。

并且有一个名为Collections.newSetFromMap()的方法,可以从任意Map实现创建一个Set

因此,您可以轻松地构建自己的实例集,如下所示:

Set<MyType> instanceSet = Collections.newSetFromMap(new IdentityHashMap<MyType,Boolean>());

看起来这是我需要的实例集的基础。太好了。谢谢。 - Jérôme Verstrynge
1
OP应该记住,以这种方式实现的Set违反了Set合同...就像IdentityHashMap违反了Map合同一样。无论如何,这可能是这样一个类不是集合框架标准部分的原因。 - Stephen C
@Stephen:确实,我忘记提到这一点了。但是通常情况下,当需要类似这样的东西时,这并不是一个大问题,因为您不会尝试将该“Set”作为“普通Set”传递。 - Joachim Sauer
我最近看到这个集合被用来修复JBoss 7中的一个bug,但我真的不明白什么时候你只想检查引用相等性 - 有人能提出一个这样的场景吗? - rich
1
@rich:我正在维护一个库,其中处理自定义对象(即由用户定义的对象)基于对象标识(即对象标识很重要,用户可以以任何方式实现equals(),它不会影响库对对象的处理)。在这种情况下,我正在使用IdentityHashMap,但我也可以看到基于标识的集合的用途。 - Joachim Sauer
2
@rich 在我的应用中,我使用标识来检测对象的更改。在某些情况下,对象是不可变的,因此当需要进行更改时会创建一个新的对象。某个系统会将其检测为新的对象,因为它不在先前的集合中,而旧对象和新对象是“相等”的。 - aalku

1
你可以像这样实现equals方法:
public boolean equals(Obect o) {
    return this == o;
}

没错,我可以这样做,但我想保留另外实现equals()方法的机会。 - Jérôme Verstrynge
1
好的 :-) 快速提醒一下,我会说几乎所有集合在尝试调用 equals 之前都会检查引用相等性。 - dacwe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接