Java:设置集合,其中项目由其类别标识

发布于 2024-08-24 18:57:36 字数 538 浏览 4 评论 0 原文

我需要 Set 集合,其中的项目将由项目类标识。类似于 Appache 的 ReferenceIdentityMap集合,但在类范围内,即同一类的两个不同实例必须在此集合中标识为相同。

你知道,这违反了 equals()/hashCode() 身份原则,但在偶尔使用时这是有道理的。

我已经用 Map、E>,但由于简单,它没有实现 Set。可能有一个更优雅的解决方案,任何 Set 的装饰器都会很棒。

是否有此类集合的实现(Apache/Google/something/... Collections)?

I need Set collection, where its items will be identified by items class. Something like ReferenceIdentityMap from Appache Collections, but on class scope i.e. two different instances of same class must be identified as same in this collection.

You know, it is a violation of equals()/hashCode() identity principle but in occasional use it makes sense.

I have done this in simple class backing with Map<Class<? extends E>, E>, but due to simplicity it doesn't implement Set<E>. There may be a more elegant solution, decorator of any Set<E> would be great.

Is there any implementation of such collection there (Apache/Google/something/... Collections)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

硪扪都還晓 2024-08-31 18:57:36

您希望覆盖集合成员的 equals() / hashCode() 的含义。我想,最简洁的方法是使用包装类:

class Wrapper<E> {

  private final E item;

  Wrapper(E item) {
    this.item = item;
  }

  E getItem() {
    return item;
  }

  public boolean equals(Object o) {
    if (!(o instanceof Wrapper)) {
      return false;
    }
    return getClass().equals(o.getClass());
  }

  public int hashCode() {
    return getClass().hashCode();
  }

}

然后您将创建一个 Set>

You wish to override the meaning of equals() / hashCode() for your set members. The cleanest way to do this, I imagine, is to use a wrapper class:

class Wrapper<E> {

  private final E item;

  Wrapper(E item) {
    this.item = item;
  }

  E getItem() {
    return item;
  }

  public boolean equals(Object o) {
    if (!(o instanceof Wrapper)) {
      return false;
    }
    return getClass().equals(o.getClass());
  }

  public int hashCode() {
    return getClass().hashCode();
  }

}

You would create a Set<Wrapper<E>> then.

水波映月 2024-08-31 18:57:36

如何扩展 HashSet 并仅重写 add(..) 方法,将 object.getClass() 而不是对象本身放入内部设置<类>,如果成功,则添加项目本身。像这样的东西

public class ClassSet<E> extends HashSet<E> {
    private Set<Class<? extends E>> classSet = new HashSet<Class<? extends E>>();

    @Override
    public boolean add(E element) {
        if (classSet.add((Class<E>) element.getClass())) {
            return super.add(element); // this actually should always return true
        }
        return false;
    }
}

How about extending HashSet and overriding just the add(..) method, putting object.getClass() instead of the object itself in an inner Set<Class<? extends E>>, and if it succeeds, adding the item itself. Something like

public class ClassSet<E> extends HashSet<E> {
    private Set<Class<? extends E>> classSet = new HashSet<Class<? extends E>>();

    @Override
    public boolean add(E element) {
        if (classSet.add((Class<E>) element.getClass())) {
            return super.add(element); // this actually should always return true
        }
        return false;
    }
}
ゞ花落谁相伴 2024-08-31 18:57:36

您可以创建一个 Comparator 类并根据它构建您的集合。您不能违反的唯一条件是,对于您尝试添加的每两个元素,compare(e1, e2) 不应抛出 ClassCastException - 这意味着您尝试插入的每两个成员应该是可比较的。

比较器类本身应该只查看对象的类,因此它是安全的。

查看构造函数

You can create a Comparator class and construct your set with it in mind. The only condition you must not violate is that for every two elements you try to add, compare(e1, e2) should not throw a ClassCastException - which means that every two members you would try to insert should be comparable.

The comparator class itself should look only at the objects' classes, so it will be safe.

Check out the constructor here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文