views:

95

answers:

9

Hi,

The following code obviously doesn't work because List<E> is abstract:

public class MyList {
    private List<E> list;

    public MyList() {
        this.list = new List<E>();
    }
}

How can I initialize MyList class with an empty constructor if I need the list variable to be a LinkedList or a ArrayList depending on my needs?

+1  A: 
boolean shouldThisBeAnArrayList=true; // Set to false to use LinkedList
if(shouldThisBeAnArrayList) {
   this.list = new ArrayList<E>();

}
else {
   this.list=new LinkedList<E>();
}
Martin Tilsted
Like I said in another comment, that would defeat the purpose of an "empty constructor" wouldn't it? I mean, I would need to pass the value of `shouldThisBeAnArrayList` somehow...
Nazgulled
+2  A: 

I'm not sure whether this is what you're asking...

public class MyList {
    private List<E> list;

    public MyList() {
        if (myNeeds)
            this.list = new LinkedList<E>();
        else
            this.list = new ArrayList<E>();
    }
}
Thomas
Sort of... I though of a solution like that but I asked here because I was thinking maybe there was a better way, somehow. Doesn't that need `myNeeds` to be passed as an argument in the constructor? That would defeat the purpose of the "empty constructor".
Nazgulled
Well, how else is the object going to know which type to use? It would either need to be passed to the constructor, or be available through the environment (e.g. some singleton class).
Thomas
That's exactly why I posted the question on SO...
Nazgulled
A: 

I would think you could do the following:

public class MyList<T> {
    private List<T> list;

    public MyList() {
        this.list = new ArrayList<T>();
    }
}
El Guapo
How would that work when I need a `LinkedList` instead of a `ArrayList`?
Nazgulled
@Nazgulled where do you want to configure the list type? Per object or perhaps in some startup properties file?
extraneon
I need it to be per object...
Nazgulled
+1  A: 

You need to determine what "your needs" are in the default case - LinkedList or ArrayList. If you can't - say, if the need changes depending on something that happens over the object's lifetime, then the list needs to change, too.

Carl Manaster
There can't be a default case...
Nazgulled
Then leave it null and create it on demand, or do without the default constructor.
Carl Manaster
+1  A: 

There are better alternatives for what you are trying to achieve:

  • Create a base class (abstract?) and override it twice, once for ArrayList and one for LinkedList
  • Inject the appropriate list to your class (dependency injection)
kgiannakakis
I had a question about that a few hours ago and someone recommended me this solution instead, look here: http://stackoverflow.com/questions/2881684/help-with-abstract-class-in-java-with-private-variable-of-type-liste
Nazgulled
+1  A: 

List is an interface and as such, cannot be constructed. Only implementations of said interface can be constructed (e.g. ArrayList). Also, you need to know the type (E) at construction.

This should work:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class MyList<E> {
    private List<E> list;

    public MyList(boolean linked) {
        if (linked) {
            list = new LinkedList<E>();
        } else {
            list = new ArrayList<E>();
        }
    }
}
Robert
This time someone suggested me that but like I said, doesn't that defeat the purpose of "empty constructor"? But maybe there's not other way... :|
Nazgulled
You could construct a LinkedList by default and have a method setListType that would construct a new ArrayList and copy data from LinkedList into it.
Robert
+2  A: 

Why not use a protected (and possibly abstract method) like:

public abstract class MyList<T> {

    protected final List<T> list;

    public MyList() {
        list = createList();
    }

    public MyList(boolean preferLinked) {
        list = preferLinked? new LinkedList<T>() : new ArrayList<T>();
    }

    // Allows client code which subclasses from MyList to override the
    // default behaviour

    protected List<T> createList() {
        return new ArrayList<T>();
    }
}
Dirk
A: 

As I understand, you cannot use just a empty constructor, because you have a decision node in your model, when you need to choose between the type of the list, so, you will have to tell the program any way what kind of list will be. This seems to be the best solution in my opinion:

public class MyList {
    private List<E> list;

    public MyList() {
        this.list = new LinkedList<E>();
    }

    //an overload for another type,
    public MyList(bool INeedArray) {
      if (INeedArray)
        this.list = new ArrayList<E>();
    }
}
Rbacarin
A: 
public class MyList<T> {
    private List<T> list = new ArrayList<T>();
}

This is what I use in classes.. I have for a long initialized what I could when defining the private variable it self.

ETHODE Web Development