包含子类实例的 Java 集合



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

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)

任何帮助。

最好使用地图和列表来完成此操作

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);

我不知道集合的任何实现,它将提供方便的方法get(key, index)因此您可能必须自己编写代码。

如其他答案中所述,您可以将其作为 Map 来执行,否则您也可以自己扩展集合 - 遗憾的是,这并不真正允许您使用 eg。列表接口来调用它,但如果使用类本身,它可以工作。它看起来像这样:

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(超类(。

看起来你要找的东西是Java的Map<K, V>。简而言之,它是键值对的集合。您可以通过调用put(K, V)来存储值,并通过调用V get(K)来访问它们 最常见的实现是 HashMap 。但是,您将无法使用Map<Class<T>, T>>因为它无法为单个键存储多个值,因此您的解决方案是将值集合存储为地图的值。为此,您需要对集合进行懒惰初始化之王,例如具有map.computeIfAbsent(key, k -> new ArrayList<>()) Map Map<Class<T>, Collection<T>>

最新更新