如何在java集中查找特定类型

时间:2013-06-20 13:02:39

标签: java collections

我有一个课程heirarchy,

Class b extends class a 
Class c extends class a

可以实例化所有三个类。 现在,这三种类型的对象被添加到Set

我需要遍历这个集合并找出类型c的实例,然后对其进行一些处理。

目前我正在遍历该集并检查每个条目是否为c的实例。

有更好的方法吗? Collections库本身有什么东西吗?

5 个答案:

答案 0 :(得分:1)

您没有准确指定所需的行为。它听起来就像你只想要c的确切实例,而不是c派生的任何类的实例。

如果是这种情况,请使用Object.getClass

x.getClass().equals(c.class);

如果xc的实例,并且不是,如果x是从{{1}派生的类的实例,则为真}}

如果不是这种情况,请使用instanceof

c

如果x instanceof c x的实例,那么这将是真的,如果cx派生的类的实例,则为真}}

无论你选择哪一个,你都想使用迭代器:

c

当然,这是一种常见的模式,并且libraries封装了这种逻辑。

答案 1 :(得分:1)

您可能需要查看lambdaj。它允许您以函数式编程方式操作集合。像这样做一个谓词:

Matcher<A> f = new Predicate<A>() {
    public boolean apply(A item) {
        return item instanceof C;
    }
};

然后只使用该谓词进行过滤。简单!

filter(f, collection)

更多信息,这里有一篇博客文章,概述了各种方法:http://guidogarcia.net/blog/2011/10/29/java-different-ways-filter-collection/

答案 2 :(得分:1)

不确定这是否适合您,但您可以使用Google Guava并在该套装上使用过滤器。让你的Predicate执行逻辑实例,然后如果为true,它将根据它过滤集合。

http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Sets.html

答案 3 :(得分:1)

您可以选择性地索引每个插入对象的类,但它主要取决于Set中的项目数和C实例的速率。

以下是一个示例类:

public class IndexedSet<T> {
  private Map<T,T> container = new HashMap<T,T>();
  private Map<Class<?>, Map<T,T>> indexByClass = new IdentityHashMap<Class<?>, Map<T,T>>();

  public boolean add(T e) {
    if (e == null) {
      throw new IllegalArgumentException("Can't add null");
    }
    if (container.containsKey(e)) return false;

    container.put(e, e);
    Map<T,T> indexEntry = indexByClass.get(e.getClass());
    if (indexEntry == null) {
      indexEntry = new IdentifyHashMap<T,T>();
      indexByClass.put(e.getClass(), indexEntry);
    }
    indexEntry.put(e,e);
    return true;
  }

  public boolean remove(T e) {
    e = container.remove(e);
    if (removed == null) return false;

    Map<T,T> indexEntry = indexByClass.get(e.getClass());
    indexEntry.remove(e);

    return true;
  }

  public Set<T> getAll() {
    return Collections.unmodifiableSet(container.keySet());
  }

  public Set<T> getByClass(Class<?> clazz) {
    Map<T,T> indexEntry = indexByClass.get(clazz);
    return indexEntry != null ? Collections.unmodifiableSet(indexEntry.keySet()) : null;
  }
}

答案 4 :(得分:1)

您可以使用SetMultimap<Class<?>, A>从具体类映射到该类的一组实例,并且仍然具有与您在containsValue方法中对应的contains方法原始集。

相关问题