16

I'm tring to create an arraylist of different class instances. How can I create a list without defining a class type? (<Employee>)

List<Employee> employees = new ArrayList<Employee>();
employees.add(new Employee());
Employee employee = employees.get(0);
jmj
  • 237,923
  • 42
  • 401
  • 438
mypolat
  • 197
  • 1
  • 1
  • 8

8 Answers8

24

You could create a list of Object like List<Object> list = new ArrayList<Object>(). As all classes implementation extends implicit or explicit from java.lang.Object class, this list can hold any object, including instances of Employee, Integer, String etc.

When you retrieve an element from this list, you will be retrieving an Object and no longer an Employee, meaning you need to perform a explicit cast in this case as follows:

List<Object> list = new ArrayList<Object>();
list.add("String");
list.add(Integer.valueOf(1));
list.add(new Employee());

Object retrievedObject = list.get(2);
Employee employee = (Employee)list.get(2); // explicit cast
Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
  • List example=new ArrayList<>(); example.get(0).myFunction(); AND List example=new ArrayList(); example.get(0).myFunction(); I used these codes but ERROR: cannot find symbol symbol: method myFunction(); – mypolat Jun 17 '12 at 18:22
  • it should be `List();` when you get the object like `example.get(0)` you need to make a explicit cast. Which class implements the method myFunction()? If `Employee` implements `myFunction()` you should do something like `((Employee)(example.get(0))).myFunction();`, with this you are indicating that the object retrieved from position 0 can be handled as an Employee. Of course if it is not an exception will be thrown. – Francisco Spaeth Jun 17 '12 at 18:31
  • class apple{ int price; public void myFunction(int iPrice) { price=iPrice; } } class orange{ int price; public void myFunction(int iPrice) { price=iPrice; } } public class main { public static void main(String[] args) { List list= new ArrayList<>(); //create 3 apple object to list list.add( new apple() ); list.add( new apple() ); list.add( new orange() ); list.get(0). /* "get(0)." this isn't using apple object and my function */ } } – mypolat Jun 17 '12 at 18:50
  • instead of `list.get(0).myFunction(..)` try `((apple)(list.get(0))).myFunction(1);` – Francisco Spaeth Jun 17 '12 at 19:00
  • check the code I paste here: http://www.heypasteit.com/clip/0DGC in order to see if this is what you are trying to do... – Francisco Spaeth Jun 17 '12 at 19:06
13
List<Object> objects = new ArrayList<Object>();

objects list will accept any of the Object

You could design like as follows

public class BaseEmployee{/* stuffs */}

public class RegularEmployee extends BaseEmployee{/* stuffs */}

public class Contractors extends BaseEmployee{/* stuffs */}

and in list

List<? extends BaseEmployee> employeeList = new ArrayList<? extends BaseEmployee>();
jmj
  • 237,923
  • 42
  • 401
  • 438
  • Use of raw types is discouraged. The Java Language Specification even states that it is possible that future versions of the Java programming language will disallow the use of raw types. Also, the use of extends would prevent adding elements to the list, as the question seems to suggest. – Edwin Dalorzo Jun 17 '12 at 18:14
  • `List` and `ArrayList` are [raw types](http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.8), aren't they? The JLS section 4.8 says: "The use of raw types is allowed only as a concession to compatibility of legacy code.The use of raw types in code written after the introduction of generics into the Java programming language is strongly **discouraged**. It is possible __that future versions of the Java programming language will disallow the use of raw types__" – Edwin Dalorzo Jun 17 '12 at 18:26
  • @Edwin, updated the answer, but I still suggest OP to use `? extends Base` pattern for such scenario – jmj Jun 17 '12 at 18:31
  • 1
    If you use the `? extends Base` in a generic type, you are allowed to get things out of the structure, but you are not allowed to put things into it. Your reference to `employeeList ` would never allow to add a new `Employee ` because it is using a wildcard reference. It would, though, to safely read whatever it already contains as a `BaseEmployee`. There is no way to do what the question suggest using wildcards, IMHO. – Edwin Dalorzo Jun 17 '12 at 18:35
3

List anyObject = new ArrayList();

or

List<Object> anyObject = new ArrayList<Object>();

now anyObject can hold objects of any type.

use instanceof to know what kind of object it is.

Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75
3

I believe your best shot is to declare the list as a list of objects:

List<Object> anything = new ArrayList<Object>();

Then you can put whatever you want in it, like:

anything.add(new Employee(..))

Evidently, you will not be able to read anything out of the list without a proper casting:

Employee mike = (Employee) anything.get(0);

I would discourage the use of raw types like:

List anything = new ArrayList()

Since the whole purpose of generics is precisely to avoid them, in the future Java may no longer suport raw types, the raw types are considered legacy and once you use a raw type you are not allowed to use generics at all in a given reference. For instance, take a look a this another question: Combining Raw Types and Generic Methods

Community
  • 1
  • 1
Edwin Dalorzo
  • 76,803
  • 25
  • 144
  • 205
1

If you can't be more specific than Object with your instances, then use:

List<Object> employees = new ArrayList<Object>();

Otherwise be as specific as you can:

List<? extends SpecificType> employees = new ArrayList<? extends SpecificType>();
pb2q
  • 58,613
  • 19
  • 146
  • 147
1

How can I create a list without defining a class type? (<Employee>)

If I'm reading this correctly, you just want to avoid having to specify the type, correct?

In Java 7, you can do

List<Employee> list = new ArrayList<>();

but any of the other alternatives being discussed are just going to sacrifice type safety.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
0

I see that all of the answers suggest using a list filled with Object classes and then explicitly casting the desired class, and I personally don't like that kind of approach.

What works better for me is to create an interface which contains methods for retrieving or storing data from/to certain classes I want to put in a list. Have those classes implement that new interface, add the methods from the interface into them and then you can fill the list with interface objects - List<NewInterface> newInterfaceList = new ArrayList<>() thus being able to extract the desired data from the objects in a list without having the need to explicitly cast anything.

You can also put a comparator in the interface if you need to sort the list.

mdenci
  • 297
  • 2
  • 6
  • 17
-1

I know this is an old question, but there's a nice and easy way to do this (it works with the mostly recent versions of ElasticSearch Rest API).

The search object goes like:

 SearchResponse<JsonData> search = client.search(s -> s
  .index(index)
  .query(query),
  JsonData.class);

And then I iterate over the response like this:

 for (Hit<JsonData> hit: search.hits().hits()) {
  String stringSource = hit.source().toString();
  MySavedRegister mySavedRegister = mapper.readValue(stringSource, mySavedRegister .class);
  mylist.add(esGenericEvent);
 }

Where mySavedRegister stands for the class that has the hits' sources parameters.