Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning List of given argument type - java

Tags:

java

generics

I have the following method

static <T> List<T> foo(List<T> arg) {

I want to create a List of the same type, call it outcome, as arg that I will eventually return. For example if

ArrayList<Integer> arg = new ArrayList<Integer>();

I want foo to return an ArrayList<Integer> as well. If

LinkedList<Integer> arg = new LinkedList<Integer>();

then I want foo to return a LinkedList<Integer>

I know List<T> outcome = new List<T>(); will not work since List is abstract, so what am I suppose to write to do what I want?

like image 724
user1529956 Avatar asked Nov 21 '12 00:11

user1529956


People also ask

How do you return a list from a method in Java?

The list() method of java. util. Collections class is used to return an array list containing the elements returned by the specified enumeration in the order they are returned by the enumeration.

What is list of () in Java?

The Java. util. List is a child interface of Collection. It is an ordered collection of objects in which duplicate values can be stored. Since List preserves the insertion order, it allows positional access and insertion of elements.

Can you have a list of different types in Java?

Thus there are four types of lists in Java i.e. Stack, LinkedList, ArrayList, and Vector.


2 Answers

You can use reflection

List<T> list = (List<T>)arg.getClass().newInstance(); // throws

You can further constraint your method signature

static<L extends List<?>> L foo(L arg) { ... }


LinkedList<Integer> x = foo( new ArrayList<Integer>() ); // doesn't compile
like image 79
irreputable Avatar answered Oct 30 '22 06:10

irreputable


When you have a certain return type, you can return any subclass of that return type, so you can return an ArrayList<T>.


EDIT (1): If you want to return a List of the same type as your argument, you could use instanceof:

static <T> List<T> foo(List<T> arg) {
    List<T> outcome = null;

    if (arg instanceof ArrayList)
        outcome = new ArrayList<T>();

    if (arg instanceof LinkedList)
        outcome = new LinkedList<T>();

    ...

    return outcome;
}

You can find a full list of the classes that implement List here.


EDIT (2): Here's another idea:

static <T, U extends List<T>> U foo(U arg) {
    U outcome = arg;    
    ... 
    return outcome;
}

You might destroy the list you pass as arg, however, but you should be able to pass a copy.

like image 3
arshajii Avatar answered Oct 30 '22 06:10

arshajii