0

There is a program which handles many lists of many types (Person, Cat, Chairs etc..).

The following code appears many times in the code. The code fills a given list with instances of type Cat until the list has a given number of instances.

int howMany = max - cats.size(); 
for(int i = 0; i < howMany; ++i) { 
 cats.add(new Cat()); 
} 

Since this code appears many time we want to create a method to replace it. The method will accept the List that we want to add instances to and the max number of instances. It can accept more parameters if needed.

This seems simple at first but then I remembered it's not possible to write new T() because of type erasure.

What other way is there to achieve this?

Shookie
  • 4,925
  • 6
  • 31
  • 56
  • Just use the generic type you used in declaring the cats list. If generics is not used, then use Object class. – Syam S Jul 18 '14 at 15:51

2 Answers2

4

You can re-use a method, that instantiates a class of a given type T.

public T getInstanceOfT(Class<T> aClass) {
   return aClass.newInstance();
}

Then, you can implement a method, that populates a given List<T> with n objects of type T.

public <T> void populateList(List<T> list, Class<T> clazz, int n) {
    for (int i = 0; i < n; i++) {
        list.add(getInstanceOfT(clazz));
    }
} 

Note1: You have to handle IllegalAccessException and InstatiationException.

Note2: If you don't want to use getInstanceOfT() you can just do clazz.newInstance() when adding to the list.

You can use the method as follows:

int howMany = max - cats.size(); 
Class<Cat> catClass = Cat.class;
List<Cat> listOfCats = new ArrayList<Cat>();
populateList(listOfCats, Cats.class, howMany);

More info:

Community
  • 1
  • 1
Konstantin Yovkov
  • 59,030
  • 8
  • 92
  • 140
  • 2
    If you're using reflection anyway, the auxiliary method is fairly pointless. Just `list.add(clazz.newInstance());` – blgt Jul 18 '14 at 15:56
0

Instead of adding all those unnecessary objects to the list, couldn't you wrap the shorter lists in an object that makes them look longer?

class PaddedList<T> extends AbstractList<T> implements List<T> {

    private final List<T> wrappedList;
    private final int size;
    private final T padding;

    public PaddedList(List<T> wrap, int size, T pad) {
        this.wrappedList = wrap;
        this.size = size;
        this.padding = pad;
    }

    @Override
    public T get(int index) {
        return index < wrappedList.size() ? wrappedList.get(index) : padding;
    }

    @Override
    public int size() {
        return size;
    }

}

public void test() {
    List<String> test = Arrays.asList("One", "Two");
    List<String> list10 = new PaddedList<>(test, 10, "Many");
    System.out.println(list10);
}

this prints

[One, Two, Many, Many, Many, Many, Many, Many, Many, Many]

Obviously this will go very wrong if you try to modify any of the objects that are used as padding but if all you want is your lists seeming like they are fixed length then this would work very efficiently.

OldCurmudgeon
  • 60,862
  • 15
  • 108
  • 197