It is necessary to use generics with ArrayList? Like this:
ArrayList<Object> software=new ArrayList<Object>();
Can I write it without it? Because I face a problem when I want to add object to it.
What I try to do is to get info from the frame and then create object and add it to tha arraylist
class Listener implements ActionListener {
public void actionPerformed(ActionEvent e) {
ArrayList software= new ArrayList();
String s = (String) major.getSelectedItem();
if((e.getActionCommand()).equals("SAVE")){
int st_id=Integer.parseInt(id.getText());
String st_name=name.getText();
String st_gender = (String) gender.getSelectedItem();
String st_major = (String) major.getSelectedItem();
String code1=code_sw1.getText();
String code2=code_sw2.getText();
String code3=code_sw3.getText();
double mark1=Double.parseDouble(m_sw1.getText());
double mark2=Double.parseDouble(m_sw2.getText());
double mark3=Double.parseDouble(m_sw3.getText());
St_Sw ob1=new St_Sw(st_id,st_name,st_gender,st_major,code1,code2,code3,mark1,mark2,mark3);
software.add(ob1);
}
}
}
What you mean is not parameter, it's a generic type. You can do a raw list like this:
List list = new ArrayList();
and it will work fine however the whole point of introducing generics in Java was to "fix" raw lists. If you store different objects than Object then it might go wrong when you for example iterate through the list and call one method on each element.
It technically isn't necessary, and you can make an ArrayList without a type and have everything work just fine.
That being said, you should consider it necessary and whenever you run into a situation where you have to not type it, you are probably doing something wrong. Chances are you should look into polymorphism/inheritance (http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29), or interfaces (http://docs.oracle.com/javase/tutorial/java/concepts/interface.html) so that you can store multiple types of objects in the same ArrayList.
The main reason you want to type all of your ArrayList is so that Java will tell you when you try to so something wrong. At first, you might think that this is causing the problem, and making it stop yelling at you is always better than it not compiling. In reality, though, if Java is yelling at you, you are doing something wrong.
In your case, it appears that the arrayList only contains St_Sw Objects. If that is the case, you would want to make your ArrayList with:
ArrayList<St_Sw> software=new ArrayList<St_Sw>();
Since Java 7 you can use the diamond operator:
ArrayList<Object> software=new ArrayList<>();
Arraylist is a dynamic array with means that new memory is allocated when you add new items to the list. There is no need to define the size before creating a arraylist. To add a object just call the add method for software.
As mentioned before,
List list = new ArrayList();
but also:
List<String> list = new ArrayList();
Is valid code in Java, and is supported for backwards compartibility reasons, as Java started having raw, non-generic types for structures like List etc. Non-generic types do not provide safety of type checking in compile time and should be avoided in new code, in general (Look here for more).
However, you can use diamond type inference for a shorthand, putting an "empty" diamond on the right side.
In Java, this
List<String> list = new ArrayList<>();
Is equal to this
List<String> a = new ArrayList<String>();
Related
This question already has answers here:
ArrayList Generic without Type
(5 answers)
Closed 5 years ago.
I have a question about the history of Java.
Java has had ArrayList since 1.2.
Java has generics since version 1.5.
How was the implementation of ArrayList without generics to define the type?
It was all done with Object (and there was a lot of casting involved), e.g.:
ArrayList list = new ArrayList();
list.add(new Thingy());
// ...
Thingy t = (Thingy)list.get(0);
// Note ---^^^^^^^^
The list only knew what it stored was Object, it was up to the code using the list to cast back to a useful type.
As you can imagine, this lead to all sorts of unpleasantness — you could put the wrong kind of object in the list, and then get ClassCastExceptions later when you tried to cast it to the type you were expecting; if you changed what was in the list, you had to change your casts everywhere and inevitably forget one, etc., etc. Generics helped remove those pain points.
Before generics, ArrayList have the Object as a type so that you can insert and get back the type Object which mean that you need to cast them while retrieving back to respected type. After generics these kind of redundant code got removed.
If you have close look at generic docs, your specific question been answered
Elimination of casts.
The following code snippet without generics requires casting:
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);
When re-written to use generics, the code does not require casting:
List<String> list = new ArrayList<String>();
list.add("hello");
String s = list.get(0); // no cast
Actually you should not ask these type of questions in stackoverflow.What everyone expects is somecode from you to debug..But anyway you seems to be like new to stackoverflow...
You can use arraylist without generics too.
For example if you use generics to hold items of particular type it looks like this..
ArrayList<String> list=new ArrayList<>();
If you don't want to use generics you can simply use this
ArrayList list =new ArrayList();
Let me tell you the very big disadvantage of using without generics.If you don't use generics then it assumes every thing as objects.So you need to type cast these to your particular datatype each time you retreive elements.
For example
for (Object o:list)
{
String s=(String)o;
System.out.println(s);
}
is what you have to do if you dont use generics..
If you use generics
then
for(String s:list)
{
System.out.println(s)
}
Hope this helps....:)
Can someone explained, as detailed as possible, the differences between the following types?
List
List<Object>
List<?>
Let me make this more specific. When would I want to use
// 1
public void CanYouGiveMeAnAnswer(List l) { }
// 2
public void CanYouGiveMeAnAnswer(List<Object> l) { }
// 3
public void CanYouGiveMeAnAnswer(List<?> l) { }
As the other posts have noted, you are asking about a Java feature called generics. In C++, this is called templates. This feature in Java is usually easier to work with than the that found in C++.
Let me answer your questions functionally (if that's not a naughty word for OO discussions).
Before generics, there were concrete classes like Vector.
Vector V = new Vector();
Vectors hold any object you give them.
V.add("This is an element");
V.add(new Integer(2));
v.add(new Hashtable());
They do this by casting all values given to it into an Object (the root of all Java classes). When you attempt to retrieve the values stored in your Vector, you need to cast the value back into the original class (if you want to do anything meaningful with it).
String s = (String) v.get(0);
Integer i = (Integer) v.get(1);
Hashtable h = (Hashtable) v.get(2);
Casting gets old fast. More than that, the compiler complains to you about unchecked casts. The most urgent problem with casting like this is that consumers of your Vector have to know the classes of its values at compile time in order to cast correctly. In cases where the producer of the Vector and the consumer of the same are completely isolated from each other (think RPC messages), this can be a fatal issue.
Enter generics. Generics attempt to create strongly typed classes to do generic operations.
ArrayList<String> aList = new ArrayList<String>();
aList.add("One");
String element = aList.get(0); // no cast needed
System.out.println("Got one: " + element);
The Design Patterns book encourages the reader to think in terms of contracts, not concrete types. There is wisdom (and code re-use) in divorcing variables from their implementing class.
With this in mind, you might think that all implementations List objects should do the same set of things: add(), get(), size(), etc. With a little reflection, you can imagine many implementations of List operations that obey the List contract in various ways (e.g. ArrayList). However, the type of data these objects deal with is orthogonal to the actions performed on them.
Put it all together and you'll see the following kinds of code frequently:
List<String> L = new ArrayList<String>();
You should read that as "L is a kind of List that deals with String objects". When you start dealing with Factory classes, it is critical to deal with contracts rather than specific implementations. Factories produce objects of various types at runtime.
Using generics is pretty easy (most of the time).
One day you may decide you want to implement your own generic class. Perhaps you want to write a new database abstraction interface that elides the differencesbetween various data stores. When you define that generic class, you will use <t> as a placeholder for the kind of object that will be manipulated by the methods.
If you are still confused, use the generic classes for List until you are comfortable. Later, you can dive into the implementation with a bit more confidence. Or you can look at the source code for the various List classes that ship with the JRE. Open source is great that way.
Have a look at the Oracle/Sun docs about generics.
Cheers.
In my own simple terms:
List
Would declare an ordinary collection, can hold any type, and will always return Object.
List<Object>
Will create a list that can hold any type of object, but can only get assigned a another List<Object>
For instance this doesn't work;
List<Object> l = new ArrayList<String>();
Of course you can add anything but only can pull Object.
List<Object> l = new ArrayList<Object>();
l.add( new Employee() );
l.add( new String() );
Object o = l.get( 0 );
Object o2 = l.get( 1 );
Finally
List<?>
Will let you assign any type, including
List <?> l = new ArrayList();
List <?> l2 = new ArrayList<String>();
This would be called collection of unknown and since the common denominator of unknown is Object you will be able to fetch Objects ( a coincidence )
The importance of unknown comes when its used with subclassing:
List<? extends Collection> l = new ArrayList<TreeSet>(); // compiles
List<? extends Collection> l = new ArrayList<String>(); // doesn't,
// because String is not part of *Collection* inheritance tree.
I hope using Collection as the type doesn't create confusion, that was the only tree that came to my mind.
The difference here, is that l is a collection of unknow that belongs to the Collection hierarchy.
To add to the already good answers here:
Method arguments:
List<? extends Foo>
good choice if you don't intend to alter the list, and only care that everything in the list is assignable to type 'Foo'. This way, the caller can pass in a List<FooSubclass> and your method works. Usually the best choice.
List<Foo>
good choice if you intend to add Foo objects to the list in your method. The caller may not pass in a List<FooSubclass>, as you intend to add a Foo to the List.
List<? super Foo>
good choice if you intend to add Foo objects to the list, and it's not important what else is in the list (ie, you are ok getting a List<Object> that contains a 'Dog' that has nothing to do with Foo).
Method return values
just like method arguments, but with the benefits reversed.
List<? extends Foo>
Guarantees that everything in the returned List has type 'Foo'. It might be List<FooSubclass> though. Caller cannot add to the List. This is your go-to choice and the most common case by far.
List<Foo>
Just like List<? extends Foo> but also allows the caller to add to the List. Less common.
List<? super Foo>
allows the caller to add Foo objects to the List, but does not guarantee what will be returned from list.get(0)... it could be anything from Foo to Object. The only guarantee is that this won't be a list of 'Dog' or some other choice that would prevent list.add(foo) from being legal. Very rare use case.
I hope that helps. Good luck!
ps. To sum up... two questions...
do you need to add to the List? Do you care what is in the list?
yes yes - use List<Foo>.
yes no - use List<? super Foo>.
no yes - use <? extends Foo> --- most common.
no no - use <?>.
I refer you to the excellent Java Generics tutorial, and the "advanced" Generics tutorial, both available from Sun Microsystems. Another great resource is the Java Generics and Collections book.
I will try to answer this in detail. Before generics we were having only List (a raw list) and it can hold almost anything we can think of.
List rawList = new ArrayList();
rawList.add("String Item");
rawList.add(new Car("VW"));
rawList.add(new Runnable() {
#Override
public void run() {
// do some work.
}
});
The major problem with the raw list is when we want to get any element out of such list it can only guarantee that it would be Object and for that reason we need to use casting as:
Object item = rawList.get(0); // we get object without casting.
String sameItem = (String) rawList.get(0); // we can use casting which may fail at runtime.
So conclusion is a List can store Object (almost everything is Object in Java) and always returns an Object.
Generics
Now lets talk about generics. Consider the following example:
List<String> stringsList = new ArrayList<>();
stringsList.add("Apple");
stringsList.add("Ball");
stringsList.add(new Car("Fiat")); //error
String stringItem = stringsList.get(0);
In the above case we cannot insert anything other than String in stringsList as Java compiler applies strong type checking to generic code and issues errors if the code violates type safety. And we get error when we try to insert a Car instance in it. Also it eliminates cast as you can check when we invoke get method. Check this link for understanding why we should use generics.
List<Object>
If you read about type erasure then you will understand that List<String>, List<Long>, List<Animal> etc. will be having different static types at compile time but will have same dynamic type List at run time.
If we have List<Object> then it can store only Object in it and almost everything is Object in Java. So we can have:
List<Object> objectList = new ArrayList<Object>();
objectList.add("String Item");
objectList.add(new Car("VW"));
objectList.add(new Runnable() {
#Override
public void run() {
}
});
Object item = objectList.get(0); // we get object without casting as list contains Object
String sameItem = (String) objectList.get(0); // we can use casting which may fail at runtime.
It seems List<Object> and List are same but actually they are not. Consider the following case:
List<String> tempStringList = new ArrayList<>();
rawList = tempStringList; // Ok as we can assign any list to raw list.
objectList = tempStringList; // error as List<String> is not subtype of List<Obejct> becuase generics are not convariant.
You can see we can assign any list to raw list and major reason for that is to allow backward compatibility. Also List<String> will be converted to List at run time due to type erasure and assignment will be fine anyways.
But List<Object> means it can only refer to a list of objects and can also store objects only. Even though String is subtype of Object we cannot assign List<String> to List<Object> as generics are not covariant like arrays. They are invariant. Also check this link for more. Also check the difference between List and List<Object> in this question.
List<?>
Now we are left with List<?> which basically means list of unknown type and can refer to any list.
List<?> crazyList = new ArrayList<String>();
List<String> stringsList = new ArrayList<>();
stringsList.add("Apple");
stringsList.add("Ball");
crazyList = stringsList; // fine
The character ? is known as wildcard and List<?> is a list of unbounded wildcard. There are certain points to observe now.
We cannot instantiate this list as the following code will not compile:
List<?> crazyList = new ArrayList<?>(); // any list.
We can say a wildcard parameterized type is more like an interface type as we can use it to refer to an object of compatible type but not for itself.
List<?> crazyList2 = new ArrayList<String>();
We cannot insert any item to it as we don't know what actually the type would be.
crazyList2.add("Apple"); // error as you dont actually know what is that type.
Now question arises When would I want to use List<?>?
You can think of this as a read-only list where you don't care about the type of the items. You can use it to invoke methods like returning the length of the list, printing it etc.
public static void print(List<?> list){
System.out.println(list);
}
You can also check the difference between List, List<?>, List<T>, List<E>, and List<Object> here.
Simplest explanation which is not "RTFM":
List
Will generate lots of compiler warnings, but is mostly equivalent to:
List<Object>
While:
List<?>
basically means its something generic, but you don't know what the generic type is. Its great for getting rid of compiler warnings when you cant modify the return types of other things that just returned List. Its much more useful in the form:
List<? extends SomeOtherThing>
The shortest possible explanation is: The second item is a list that can hold any type, and you can add objects to it:
List<Object>
The first item you list is treated as essentially equivalent to this, except you will get compiler warnings because it is a "raw type".
List
The third is a list that can hold any type, but you cannot add anything to it:
List<?>
Basically, you use the second form (List<Object>) when you truly have a list that can contain any object and you want to be able to add elements to the list. You use the third form (List<?>)when you receive the list as a method return value and you will iterate over the list but never add anything to it Never use the first form (List) in new code compiling under Java 5 or later.
I'd put it this way: While List and List<Object> can contain any type of objects, List<?> contains elements of an unknown type, but once that type is captured, it can only contain elements of that type. Which is why it is the only type safe variant of those three, and therefore generally preferable.
To complement the tutorials mentioned by Rob, here's a wikibook explaining the topic:
http://en.wikibooks.org/wiki/Java_Programming/Generics
Edit:
No restrictions on type of items in list
Items in list must extend Object
Wildcard used by itself, so it matches anything
Would it be naive of me to conclude at this point that there's hardly any/no difference at all?
When would I want to use
public void CanYouGiveMeAnAnswer( List l ){}
When you cant to do all the casting your self.
When would I want to use
public void CanYouGiveMeAnAnswer( List l<Object> ){}
When you want to restrict the type of the List. For instance, this would be an invalid argument.
new ArrayList<String>();
When would I want to use
public void CanYouGiveMeAnAnswer( List l<?> ){}
Mostly never.
List, List<?>, and List<? extends Object> are the same thing. The second is more explicit. For a list of this type, you cannot know what types are legal to put into it, and you don't know anything about the types you can get out of it, except that they will be objects.
List<Object> specifically means that the list contains any sort of object.
Let's say we make a list of Foo:
List<Foo> foos= new ArrayList<Foo>();
It is not legal to put a Bar into foos.
foos.add(new Bar()); // NOT OK!
It is always legal to put anything into a List<Object>.
List<Object> objs = new ArrayList<Object>();
objs.add(new Foo());
objs.add(new Bar());
But you mustn't be allowed to put a Bar into a List<Foo> - that's the whole point. So that means that this:
List<Object> objs = foos; // NOT OK!
is not legal.
But it's ok to say that foos is a list of something but we don't know specifically what it is:
List<?> dontKnows = foos;
But that then means that it must be prohibited to go
dontKnows.add(new Foo()); // NOT OK
dontKnows.add(new Bar()); // NOT OK
because the variable dontKnows does't know what types are legal.
List < Object > is meant to pass input type parameter of an Object. While List < ? > represents Wildcard type. The wildcard < ? > is of Unknown parameter type. The wildcard cannot be used as a type argument for a generic method and cannot be used to create a generic instance of a class. Wildcard can be used to extend a subtype class, List < ? extends Number >. To relax the restriction of an Object type and in this case to relax "Number" Object type.
In terms of List functionality differences, the other responses already answered this question. In terms of applicable rules of Java generics, it's a complicated topic. I wrote an in-depth article about Java generics rules, this is the link: https://medium.com/#royalilin/java-generics-rules-1d05de86e9cb
Code 1:
ArrayList arr = new ArrayList();
arr.add(3);
arr.add("ss");
Code 2:
ArrayList<Object> arr = new ArrayList<Object>();
arr.add(3);
arr.add("ss");
Code 3:
ArrayList<Object> arr = new ArrayList<Object>();
arr.add(new Integer(3));
arr.add(new String("ss"));
all the above three codes are working fine.. can some one tell me the which is prefered and why.. and why the eclipse compiler always gives warning when type of arguments are not mentioned to the Arraylist.. thanks in advance..
First simple rule: never use the String(String) constructor, it is absolutely useless (*).
So arr.add("ss") is just fine.
With 3 it's slightly different: 3 is an int literal, which is not an object. Only objects can be put into a List. So the int will need to be converted into an Integer object. In most cases that will be done automagically for you (that process is called autoboxing). It effectively does the same thing as Integer.valueOf(3) which can (and will) avoid creating a new Integer instance in some cases.
So actually writing arr.add(3) is usually a better idea than using arr.add(new Integer(3)), because it can avoid creating a new Integer object and instead reuse and existing one.
Disclaimer: I am focusing on the difference between the second and third code blocks here and pretty much ignoring the generics part. For more information on the generics, please check out the other answers.
(*) there are some obscure corner cases where it is useful, but once you approach those you'll know never to take absolute statements as absolutes ;-)
The second one would be preferred:
it avoids unnecessary/inefficient constructor calls
it makes you specify the element type for the list (if that is missing, you get a warning)
However, having two different types of object in the same list has a bit of a bad design smell. We need more context to speak on that.
The second form is preferred:
ArrayList<Object> arr = new ArrayList<Object>();
arr.add(3);
arr.add("ss");
Always specify generic arguments when using generic types (such as ArrayList<T>). This rules out the first form.
As to the last form, it is more verbose and does extra work for no benefit.
Actually, a third is preferred:
ArrayList<Object> array = new ArrayList<Object>();
array.add(Integer.valueOf(3));
array.add("ss");
This avoids autoboxing (Integer.valueOf(3) versus 3) and doesn't create an unnecessary String object.
Eclipse complains when you don't use type arguments with a generic type like ArrayList, because you are using something called a raw type, which is discouraged. If a class is generic (that is, it has type parameters), then you should always use type arguments with that class.
Autoboxing, on the other hand, is a personal preference. Some people are okay with it, and some not. I don't like it, and I turn on the warning for autoboxing/autounboxing.
You are getting the warning because ArrayList is part of java generics. Essentially, it's a way to catch your type errors at compile time. For example, if you declare your array list with types Integer (ArrrayList<Integer>) and then try to add Strings to it, you'll get an error at compile time - avoiding nasty crashes at runtime.
The first syntax is there for backward compatibility and should be avoided whenever possible (note that generics were not there in older versions of java).
Second and third examples are pretty much equivalent. As you need to pass an object and not a primitive type to add method, your 3 is internally converted to Integer(3). By writing a string in double-quotes you effectively are creating a String object. When calling String("ss") you are creating a new String object with value being the same as the parameter ("ss").
Unless you really do need to store different types in your List, I would suggest actually using a proper type declaration, e.g. ArrayList<Integer> = new ArrayList<Integer>() - it'll save you a lot of headache in the long run.
If you do need multiple datatypes in the list, then the second example is better.
Two last variants are the same, int is wrapped to Integer automatically where you need an Object. If you not write any class in <> it will be Object by default. So there is no difference, but it will be better to understanding if you write Object.
Well by doing the above you open yourself to run time errors, unless you are happy to accept that your arraylists can contains both strings and integers and elephants.
Eclipse returns an error because it does not want you to be unaware of the fact that by specifying no type for the generic parameter you are opening yourself up for run time errors. At least with the other two examples you know that you can have objects in your Arraylist and since Inetegers and Strings are both objects Eclipse doesn't warn you.
Either code 2 or 3 are ok. But if you know you will have either only ints or only strings in your arraylist then I would do
ArrayList<Integer> arr = new ArrayList<Integer>();
or
ArrayList<String> arr = new ArrayList<String>();
respectively.
There's a faster and easy way in Java 9 without involving much of code: Using Collection Factory methods:
List<String> list = List.of("first", "second", "third");
in the first you don't define the type that will be held and linked within your arraylist construct
this is the preferred method to do so, you define the type of list and the ide will handle the rest
in the third one you will better just define List for shorter code
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Java Generics
To be more specific, whats the role of the <String> in the following line of code?
private List<String> item = new ArrayList<String>();
Mainly to allow the compiler to raise an error if you don't insert the right kind of data into the list or if you expect data of the wrong type from the list at the moment of extraction
But see the generics tutorial for an explanation: http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html
It means that the list can only contain items of the String type. It can't contain items of Number, SomeObject, WhateverType types.
It's called Generics. In Java, it's actuallty compile time syntactic sugar to make the code more robust without the risk for ClassCastException and consorts on retrieving the list items during runtime. You can find here a Sun tutorial on the subject, it also explains the reasoning behind the move to Generics.
Thats Generics - allowing the compiler to keep track of what is inside lists etc. Notoriously tricky in Java.
Here is an excellent description: http://www.infoq.com/resource/articles/bloch-effective-java-2e/en/resources/Bloch_Ch05.pdf
Those are generics and where introduced on the v1.5 of Java
They allows you to provide compile time check of the class being used.
You can read the declaration:
private List<String> item = new ArrayList<String>();
As:
private List of Strings named item initialized with an ArraysList of Strings
So, if you attempt to put something that's not a String you'll get a compile time exception:
private List<String> items = new ArrayList<String>();
...
items.add( new Date() ); // fails at compilation time
When you get something from that list you'll get a list
private List<String> item = new ArrayList<String>();
...
items.add( "Hello" );
String s = items.get(0);// returns
To use different classes you provide a different type:
private List<Date> dates = new ArrayList<Date>();
And now you can only use Dates with that collection.
The reason for your this new Java Edition after JDK 1.5 or later as it gives more ease to the programmer as it allow type safety at compile type only.
The million dollar question is why it is needed so?
The answer is let say you have List in which you want to add integer type objects only into it like below
List list = new ArrayList();
list.add(new Integer(5));
but by mistake you add String object into it.
list.add("Test");
Now in you other code you are using this list assuming that all values are integer
(Integer)list.get(2);
this will give error at run time, so to avoid this it is better to defined your list at declaration part like list and it will not allow you to add string object to you.
I am new to Java, so I am not aware of the nitty gritties.
Why can't I create generic array of parametrized ArrayList?
Instead I have to write,
ArrayList<String>[] alist = new ArrayList[10];
or I have to create List of ArrayLists.
Aren't arrays supposed to be more efficient than ArrayLists? Then why doesn't Java allow it?
Also, what is the difference between following two lines.
ArrayList<String>[] alist = new ArrayList[10];
ArrayList<String>[] alist = new ArrayList<?>[10];
The reason you have to do that is because generics don't really exist in Java. It's actually a compiler hack.
As for the two lines you posted, there shouldn't be any difference in terms of the bytecode produced. However, in the first case you'll probably get a warning because your compiler thinks you forgot java.util.ArrayList wants a type parameter, whereas the latter won't compile because you're trying to instantiate a generic array. Lose-lose situation :(
Actually the implementation of ArrayList is very efficient for read and write actions that don't change the size of the list. In many cases (at least since java 1.6) the compiler will totally remove the method call overhead (for instance for get()).
Also not many programs require the performance that an array offers, so don't worry about using arrays until your code is too slow (and even then you probably don't need the arrays)
If you could do that, this will happen :
ArrayList<String>[] alist = new ArrayList<String>[10];
Object[] olist = alist; // This is okay because ArrayList is an Object
olist[0] = new ArrayList<Dog>();
olist[0].add(new Dog());
String s = alist[0].get(0); //Uh oh, Dog is not string
I would also recommend creating an arraylist of arraylists.
ArrayList<ArrayList<Type>> alist = new ArrayList<ArrayList<Type>>();
, where Type is whatever type you wanted the list to be. You now have an arraylist that holds array lists. If you want to add an arraylist, you can do:
alist.add(new ArrayList<Type>());