是否有我可以使用的地图会阻止.equals()重复?

时间:2014-08-22 17:53:42

标签: java map hashmap identity equality

我想要一个Map<?, ?>来防止重复,但不仅是内存重复,而是重复,其中对象中的所有内容都具有相同的值,即.equals()== true。有谁知道我怎么能做到这一点?

2 个答案:

答案 0 :(得分:2)

Map接口指定键的比较是相等的(.equals):

  

public interface Map<K,V>

     

public V get(Object key)

     

...。更正式的说,如果此地图包含从密钥k到a的映射   值v使得(key==null ? k==null : key.equals(k)),然后是这个   方法返回v;否则返回null。 (最多可以有一个   这种映射。)

当然,界面的文档。 Java类型系统实际上强制执行该行为成立。但是,大多数Map的实现都尊重它。例如,这是您在HashMap中看到的行为。

Map的一个实现,它基于身份(==)而不是相等(.equals)。它被称为IdentityHashMap。它的文档明确地提到了这样的事实:这种行为对于Map的实现来说并不典型,事实上,它违反了 Map的契约(强调存在于原始版本中):

public class IdentityHashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Serializable, Cloneable
     

... 此类不是通用的Map实现!虽然这个类实现了Map接口,但它故意违反了Map   一般合同,强制要求使用equals方法   比较对象。此类仅适用于罕见的类   需要引用等同语义的情况。

答案 1 :(得分:0)

您正在搜索双向映射,请使用Guava的BiMap

即:映射为双射函数:

y = map.get(x)
x = map.inverse.get(y)

<强> 校正:

@JoshuaTaylor评论说,似乎我误解了这个问题。

也许,也许,真正想要的是,没有多个同等对象的实例。

class Unique {

    private static Map<Object, Object> identityMap = new HashMap<>();

    public static <T> T share(T object, Class<T> type) {
        Object old = identityMap.get(object);
        if (old == null) {
            old = object;
            identityMap.put(old, old);
        }
        return type.cast(old);
    }
}

使用方法:

Xxx x = ...
x = Unique.share(x, Xxx.class);

这导致x成为第一个相等的实例。

可能弱的参考地图会更好。