为单个类实例设置

时间:2012-02-14 14:28:35

标签: java

我有Set个对象,我不想允许在那里存储任何类的多个实例。哪种解决方案最好:

  • 检查集合中是否存在给定类的实例(似乎效率不高)
  • 实施hashCode以返回常量,equals返回o != null && o.getClass() == getClass()
  • 自己实现Set(几乎像第一个选项)
  • 其他什么?也许已经有这么一套?

4 个答案:

答案 0 :(得分:5)

我会使用Map<Class<? extends T>, T>


示例实施:

class SingleInstanceSet<T> {

    Map<Class<? extends T>, T> map = new HashMap<Class<? extends T>, T>();

    public boolean add(T o) {

        if (map.containsKey(o.getClass()))
            return false;

        map.put((Class<? extends T>) o.getClass(), o);
        return true;
    }

    public T get(Class<? extends T> klass) {
        return map.get(klass);
    }
}

使用示例:

public static void main(String[] args) {
    ClassSet<Object> instances = new ClassSet<Object>();

    instances.add("hello");
    instances.add(1234);
    instances.add("will not be added");

    System.out.println(instances.map);
}

输出类似:

{class java.lang.String=hello, class java.lang.Integer=1234}

答案 1 :(得分:1)

使用HashMap。在添加对象之前,获取它的类(使用反射)并检查它是否已经是HashMap中的键。

答案 2 :(得分:0)

你可以 invent 实现一个小的包装类并存储而不是实例:

 public class InstanceWrapper {
   private Object obj;
   public InstanceWrapper(Object obj) { this.obj = obj; }
   public Object getObject() { return obj; }

   @Override
   public boolean equals(Object other) {
     return this.getClass().equals(other.getClass());
   }

   @Override
   public int hashCode() {
     return this.getClass().hashCode());
   }
 }

由于通过类实例定义了相等性,因此一个集合只接受任何类的一个实例。

答案 3 :(得分:0)

Guava提供ClassToInstanceMap,已经检查过安全性,测试等。它就像Map<Class<T>, T>,但它已经处理了所有类型系统的东西。