我需要使用基本类的子类集合,这是问题的描述:
class A {
}
class B extends A{
}
class C extends A{
}
class D extends A{
}
我需要使用一个集合,该集合只能按类型获取子类的实例,这意味着当我需要从集合中获取A类的实例时,我需要像这样:
c.get(B.class);
如果我有多个来自同一类型的实例,我想按类型和索引检索该实例:
示例:c.get(B.class, 0), c.get(B.class, 1), c.get(C.class)
任何帮助。
答案 0 :(得分:1)
最好使用Map and List来实现
Map<Class, List<? extends A>> map = new HashMap<>()
然后您将添加如下元素:
void addElement(final A element)
if (!map.containsKey(element.getClass())){
map.put(element.getClass(), new LinkedList<>());
}
map.get(element.getClass()).add(element);
}
您将可以通过
获取特定类的第n个实例map.get(<Class here>).get(n);
我不知道Collection的任何实现,它将提供方便的方法get(key, index)
,因此您可能必须自己编写代码。
答案 1 :(得分:1)
如其他答案中所述,您可以将其作为Map进行操作,否则也可以自己扩展一个集合-可悲的是,这实际上不允许您使用eg。 List接口可以调用它,但是如果您使用类本身,它就可以工作。看起来像这样:
class InstanceArrayList<T> extends ArrayList<T>
{
public <V> V get(Class<V> instanceClass){
return (V) this.stream()
.filter( e -> e.getClass().equals( instanceClass ) )
.findFirst()
.orElse( null );
}
public <V> V get(Class<V> instanceClass, int index){
return (V) this.stream()
.filter( e -> e.getClass().equals( instanceClass ) )
.skip( index ).findFirst()
.orElse( null );
}
}
它会警告您有关未经检查的强制转换-但由于我们已经知道对象类型匹配,因此我们可以安全地忽略它。
然后您可以像这样使用它:
public static void main( String[] args )
{
InstanceArrayList<A> it = new InstanceArrayList<>();
it.add( new A() );
it.add( new A() );
it.add( new B() );
it.add( new B() );
it.add( new C() );
it.add( new C() );
System.out.println(it.get( A.class ));
System.out.println(it.get( A.class, 1 ));
System.out.println(it.get( B.class ));
System.out.println(it.get( B.class, 1 ));
System.out.println(it.get( C.class ));
System.out.println(it.get( C.class, 1 ));
}
如果您不希望它返回子类,也可以轻松地使其返回T(超类)。
答案 2 :(得分:0)
您所寻找的东西似乎是Java的<f:if condition="{mediaElement.type} == 2">
<div class="news-video">preview image</div>
</f:if>
。简而言之,它是键值对的集合。您可以通过调用Map<K, V>
来存储值,并通过调用put(K, V)
来访问它们,最常见的实现是V get(K)
。
但是,您将无法使用HashMap
,因为它不能为单个键存储多个值,因此您的解决方案是将值的集合存储为地图的值。
为此,您将需要延迟初始化集合之王,例如将Map<Class<T>, T>>
用于map.computeIfAbsent(key, k -> new ArrayList<>())