13

我知道IdentityHashSet(通过Collections#newSetFromMap(Map))和LinkedHashSet。但是,我需要的是两者的结合,一个LinkedIdentityHashSet. 我在网上找不到任何现成的解决方案。有人知道如何调整这个吗?

谢谢你的建议!

4

3 回答 3

7

那里的实现技术并没有很好地结合起来。LinkedHashMap将链接列表添加到地图的条目对象中。IdentityHashMap使用探测技术,因此避免了任何入口对象。

有几种方法可以将“身份”特征添加到集合/地图中。

  • final equals使用和hashCode方法强制键类型正确运行。真的所有引用类型都应该有这个,但没关系。
  • 如果您不能修改equalshashCode可以修改该类,请添加一个属于该类的final字段,该字段final包含final对您将用作键的类型的引用。使用新字段作为键。
  • 将适配器对象存储在集合/映射中。您需要为每个查找创建一个新的适配器实例。它只是有它的equals/hashCode方法来调用==/System.identityHashCode在原始对象上。
于 2013-06-24T13:36:04.243 回答
4

一种选择是使用 LinkedHashSet 和包装器

class LinkedIdentityHashSet<E> extends AbstractSet<E> {
    Set set = new LinkedHashSet();

    static class IdentityWrapper {
        Object obj;

        IdentityWrapper(Object obj) {
            this.obj = obj;
        }

        public boolean equals(Object obj) {
            return this.obj == obj;
        }

        public int hashCode() {
            return System.identityHashCode(obj);
        }
    }

    public boolean add(E e) {
        return set.add(new IdentityWrapper(e));
    }
...
于 2013-06-24T14:01:03.010 回答
0

您可以实现一个自定义 Map,该 Map 使用使用身份语义的 Wrapper 对象,并在内部使用使用这些 Wrapper 对象的 LinkedHashSet。

于 2013-06-24T13:42:24.943 回答