我有一个阶级层次,
Class b extends class a
Class c extends class a
这三个类都可以实例化。现在这三种类型的对象被添加到一个Set
.
我需要遍历这个集合并找出类型 c 的实例,然后对其进行一些处理。
目前我正在遍历集合并检查每个条目是否为 instanceof c 。
有没有更好的方法来做到这一点?Collections
图书馆本身的东西?
我有一个阶级层次,
Class b extends class a
Class c extends class a
这三个类都可以实例化。现在这三种类型的对象被添加到一个Set
.
我需要遍历这个集合并找出类型 c 的实例,然后对其进行一些处理。
目前我正在遍历集合并检查每个条目是否为 instanceof c 。
有没有更好的方法来做到这一点?Collections
图书馆本身的东西?
您没有准确指定您想要的行为。听起来您只想要 的确切实例c
,而不是派生自 的任何类的实例c
。
如果是这种情况,请使用Object.getClass
:
x.getClass().equals(c.class);
如果x
是 的实例,则为真,如果是派生自的类的实例c
,则不为真。x
c
如果不是这种情况,请使用instanceof
:
x instanceof c
如果是的x
实例c
,则为真,如果是派生自的类的实例,则为真。x
c
无论您选择哪一个,您都想从那里使用迭代器:
Iterator<a> iter = set.iterator();
while(iter.hasNext()) {
a item = iter.next()
if(item[.getClass().equals(c.class)| instanceof c]) {
// do something with item
}
}
当然,这是一种常见的模式,也有封装这种逻辑的库。
您可以选择索引每个插入对象的类,但这主要取决于 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;
}
}
您可以使用 aSetMultimap<Class<?>, A>
从具体类映射到该类的一组实例,并且仍然具有与原始集合中的方法containsValue
相对应的contains
方法。
您可能想研究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/
不确定这是否适合您,但您可以使用 Google Guava 并在该集合上使用过滤器。让您的 Predicate 执行 instanceof 逻辑,然后如果为 true,它将根据该逻辑过滤集合。
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Sets.html