As noted in other answer, you can do it as Map, otherwise you can also extend a collection yourself - this sadly doesn't really allow you to use eg. List interface to call it, but it works if you use the class itself. It would look something like this:
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 );
}
}
It will warn you about unchecked cast - but we can ignore it safely, since we already know the object type matches.
And then you can just use it like this:
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 ));
}
If you don't want it to return child class, you can also easly make it return T (superclass) instead.