How to have Java method return generic list of any type?
Mia Lopez
I would like to write a method that would return a java.util.List of any type without the need to typecast anything:
List<User> users = magicalListGetter(User.class);
List<Vehicle> vehicles = magicalListGetter(Vehicle.class);
List<String> strings = magicalListGetter(String.class);What would the method signature look like? Something like this, perhaps(?):
public List<<?> ?> magicalListGetter(Class<?> clazz) { List<?> list = doMagicalVooDooHere(); return list;
} 1 8 Answers
private Object actuallyT;
public <T> List<T> magicalListGetter(Class<T> klazz) { List<T> list = new ArrayList<>(); list.add(klazz.cast(actuallyT)); try { list.add(klazz.getConstructor().newInstance()); // If default constructor } ... return list;
}One can give a generic type parameter to a method too. You have correctly deduced that one needs the correct class instance, to create things (klazz.getConstructor().newInstance()).
No need to even pass the class:
public <T> List<T> magicalListGetter() { return new ArrayList<T>();
} 2 Another option is doing the following:
public class UserList extends List<User>{
}
public <T> T magicalListGetter(Class<T> clazz) { List<?> list = doMagicalVooDooHere(); return (T)list;
}
List<User> users = magicalListGetter(UserList.class);`
Let us have List<Object> objectList which we want to cast to List<T>
public <T> List<T> list(Class<T> c, List<Object> objectList){ List<T> list = new ArrayList<>(); for (Object o : objectList){ T t = c.cast(o); list.add(t); } return list;
} You can use the old way:
public List magicalListGetter() { List list = doMagicalVooDooHere(); return list;
}or you can use Object and the parent class of everything:
public List<Object> magicalListGetter() { List<Object> list = doMagicalVooDooHere(); return list;
}Note Perhaps there is a better parent class for all the objects you will put in the list. For example, Number would allow you to put Double and Integer in there.
Something like this
publiŃ <T> List<T> magicalListGetter(Class<T> clazz) { List list = doMagicalVooDooHere(); return list;
} 2 You can simply cast to List and then check if every element can be casted to T.
public <T> List<T> asList(final Class<T> clazz) { List<T> values = (List<T>) this.value; values.forEach(clazz::cast); return values;
} I'm pretty sure you can completely delete the <stuff> , which will generate a warning and you can use an, @ suppress warnings. If you really want it to be generic, but to use any of its elements you will have to do type casting. For instance, I made a simple bubble sort function and it uses a generic type when sorting the list, which is actually an array of Comparable in this case. If you wish to use an item, do something like: System.out.println((Double)arrayOfDoubles[0] + (Double)arrayOfDoubles[1]); because I stuffed Double(s) into Comparable(s) which is polymorphism since all Double(s) inherit from Comparable to allow easy sorting through Collections.sort()
//INDENT TO DISPLAY CODE ON STACK-OVERFLOW
@SuppressWarnings("unchecked")
public static void simpleBubbleSort_ascending(@SuppressWarnings("rawtypes") Comparable[] arrayOfDoubles)
{
//VARS //looping int end = arrayOfDoubles.length - 1;//the last index in our loops int iterationsMax = arrayOfDoubles.length - 1; //swapping @SuppressWarnings("rawtypes") Comparable tempSwap = 0.0;//a temporary double used in the swap process int elementP1 = 1;//element + 1, an index for comparing and swapping
//CODE //do up to 'iterationsMax' many iterations for (int iteration = 0; iteration < iterationsMax; iteration++) { //go through each element and compare it to the next element for (int element = 0; element < end; element++) { elementP1 = element + 1; //if the elements need to be swapped, swap them if (arrayOfDoubles[element].compareTo(arrayOfDoubles[elementP1])==1) { //swap tempSwap = arrayOfDoubles[element]; arrayOfDoubles[element] = arrayOfDoubles[elementP1]; arrayOfDoubles[elementP1] = tempSwap; } } }
}//END public static void simpleBubbleSort_ascending(double[] arrayOfDoubles) 0