包含子类实例的Java集合

时间:2019-02-07 09:52:58

标签: java collections

我需要使用基本类的子类集合,这是问题的描述:

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)

任何帮助。

3 个答案:

答案 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<>())