Hydraxy
Hydraxy

Reputation: 289

Java: Implementing a generic method which instantiates a collection of a particular type

I would like to implement a generic method which does something akin to the following:

private <T> void addToSize(ArrayList<T> list, Class<T> type, int size) {
    int currentSize = list.size();

    for(int i = currentSize; i < size; i++) {
        try {
            list.add(type.newInstance());
        } catch (InstantiationException e) {
            logger.error("", e);
        } catch (IllegalAccessException e) {
            logger.error("", e);
        }
    }
}

The method above works for something like so:

ArrayList<Integer> test = new ArrayList<Integer>();
addToSize(test, Integer.class, 10);

but I also want it to work for...

ArrayList<ArrayList<Integer>> test = new ArrayList<ArrayList<Integer>>();
addToSize(test, ArrayList.class, 10); //Is this possible?

Is this possible?

Upvotes: 4

Views: 187

Answers (2)

newacct
newacct

Reputation: 122519

You could do this

ArrayList<ArrayList<Integer>> test = new ArrayList<ArrayList<Integer>>();
addToSize(test, (Class<ArrayList<Integer>>)(Class<?>)ArrayList.class, 10);

Class literals are always Class parameterized with the raw type. Getting it into a Class parameterized with something generic is somewhat tricky.

Upvotes: 0

Bohemian
Bohemian

Reputation: 425348

You could use the factory pattern:

public interface Factory<T> {
    public T create();
}

private static <T> void addToSize( ArrayList<T> list, Factory<T> factory, int size ) {
    int currentSize = list.size();

    for ( int i = currentSize; i < size; i++ ) {
        list.add( factory.create() );
    }
}

Then for your example (implemented anonymously):

ArrayList<ArrayList<Integer>> test2 = new ArrayList<ArrayList<Integer>>();
addToSize( test2, 
    new Factory<ArrayList<Integer>>() {
       public ArrayList<Integer> create() { 
           return new ArrayList<Integer>( );
       }
    }, 10 ); // compiles

The cool thing about this is the class doesn't need a default constructor, and you could pass values into its constructor and/or use the builder pattern. The complexity of the create() method implementation is arbitrary.

Upvotes: 6

Related Questions