Initialize an Array of ArrayList [duplicate] - java

This question already has answers here:
How can I create an Array of ArrayLists?
(20 answers)
Closed 9 years ago.
How can I initialize an Array of ArrayList<String>?
I tried this syntax but it didn't work:
ArrayList<String>[] subsection = new ArrayList<String>[4];

you can define like this :
ArrayList<String>[] lists = (ArrayList<String>[])new ArrayList[10];
lists[0] = new ArrayList<String>();
lists[0].add("Hello");
lists[0].add("World");
String str1 = lists[0].get(0);
String str2 = lists[0].get(1);
System.out.println(str1 + " " + str2);

That syntax works fine for the non-generic ArrayList. (ideone)
But it won't work for the generic ArrayList<E>: (ideone)
This code:
ArrayList<String>[] subsection = new ArrayList<String>[4];
Gives a compiler error:
Main.java:8: generic array creation
ArrayList<String>[] subsection = new ArrayList<String>[4];
For the generic version use an ArrayList<ArrayList<E>>:
ArrayList<ArrayList<String>> subsection = new ArrayList<ArrayList<String>>();

Okay after comment, I thought well... your right why not.
Figured it out.
ArrayList[] test = new ArrayList[4];
test[3] = new ArrayList<String>();
test[3].add("HI");
System.out.println(test[3].get(0));
Though I will be honest, I am not really sure WHY this works.
Once you assign the first item of test as a new Collection, it will only allow all other items in the array to be that type. So you couldn't do
test[3] = new ArrayList<String>();
test[2] = new HashSet<String>();

Look into generics as type clarification process, you can assign typed value to a variable of raw type AND vice versa. In core generics are a shortcut for the programmers to avoid making type casting too much, which also helps to catch some logical errors at compile time.
At the very basics ArrayList will always implicitly have items of type Object.
So
test[i] = new ArrayList<String>(); because test[i] has type of ArrayList.
The bit
test[3] = new ArrayList<String>();
test[2] = new HashSet<String>();
did not work - as was expected, because HashSet simply is not a subclass of ArrayList. Generics has nothing to do here. Strip away the generics and you'll see the obvious reason.
However,
test[2] = new ArrayList<String>();
test[3] = new ArrayList<HashSet>();
will work nicely, because both items are ArrayLists.
Hope this made sense...

Related

What is the difference List<String> list = new LinkedList<>() vs List list = new LinkedList<String>()? [duplicate]

This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 3 years ago.
I found a problem when I am using java generics.
List list = new LinkedList<String>();
list.add(MyObject); //No
prompts for any compilation errors.This is not I want
If I use :
List<String> list = new LinkedList<>();
list.add(MyObject); //Prompt for compilation errors.This is what I want
I wanna know what is the difference between
List<String> list = new LinkedList<>() and
List list = new LinkedList<String>() and
List<String> list = new LinkedList<String>() and
List<String> list = new LinkedList()?
List<String> list = new LinkedList<String>(); does the following:
Declare a variable called list with type List<String>
Call the constructor of LinkedList with the type parameter String
Sets the value of list to the result of step 2.
Since a List<String> is obviously not going to be given a new LinkedList<Elephant>();, it is OK to remove the type parameter from the second part, giving: List<String> list = new LinkedList<>();. This is called "Type Inference". Java can only do this when it can calculate at compile-time what the omitted type would be.
If you use List list = new LinkedList<String>();, you do exactly the same thing as above, except your new variable list does not contain type information. This can be dangerous, as it prevents the compiler from warning/stopping you when you do something that would cause a type error.
For example:
List<String> list = new LinkedList<>();
list.add("hello"); // works fine
list.add(123); // compile-time error
I have been saved from putting an int into a list of Strings. However, if using a regular List:
List list = new LinkedList<String>();
list.add("hello"); // stil works
list.add(123); // also works
The issue with this comes from when you then retrieve items from the list:
List list = new LinkedList<String>();
list.add(123); // allowed
Object obj = list.get(0); // is obj a String? is it an int?
This breaks type safety, which is arguably a strong reason for using Java in the first place.

Generics and Collections, don`t understand

Is there any difference between these 3 lines?
List list2 = new ArrayList<String>();
List list2 = new ArrayList<>();
List list2 = new ArrayList();
As I understand, all information about generics is erased in runtime. Consequently, only type of veriable is important. So the above lines of code mean the same thing to me. If I am wrong can anybody give me some exapmle that shows the difference?
p.s. sorry for my english
While it is true that generic data is erased at compile-time, that doesn't mean they are totally useless. The only line that would compile in your example is the last one, but you would get a warning that you are using RawTypes. A RawType is a generic class that does not have a generic object. The first two lines are only half-built.
The reason you pretty much have to use generics is that the list is type-safe. If you use generics, you could use something like this:
List<String> list = new ArrayList<>();
String out = list.get(0);
If you use raw types, you would have to do this:
List list = new ArrayList();
String out = (String) list.get(0);
This may seem OK, but what if you add a value to the list that is not a String? The program crashes. For example:
List unsafe = new ArrayList();
List<String> safe = new ArrayList<>();
unsafe.add("hi");
unsafe.add(new Tree());
safe.add("hi");
safe.add(new Tree()); // This line would throw an exception.
String out = (String) unsafe.get(0);
String out1 = safe.get(0);
String out2 = (String) unsafe.get(1); // This line would throw an exception.
If you still don't quite see why to use generic types, the final nail in the coffin for raw types is this: If my (String) unsafe.get(1) is in a separate class, on the hundredth line, I know that that line is the problematic line. I, however, don't know where the non-string object is being added, only where it's being accessed.
If you use generic types, you know exactly where the problematic addition is made, and you can prevent it.

Another way to convert ArrayList containing Strings to an array of Strings in Java?

I have checked the following stackoverflow source to solve my problem:
StackOverflow link
but, when applying the top solution, I still get an error, as follows:
My list is defined here:
List linhaInicial = new ArrayList();
My convertion is made here:
String[] convertido = linhaInicial.toArray(new String[linhaInicial.size()]);
The problem is I still get the following error:
Error:(86, 59) java: incompatible types
required: java.lang.String[]
found: java.lang.Object[]
My conversion is somehow still returning Object[] when it should now be returning String[].
Any solutions?
Thanks!
Do not use raw types!
List linhaInicial = new ArrayList();
should be
List<String> linhaInicial = new ArrayList<>();
Change :
List linhaInicial = new ArrayList(); // can contain any Object.
//So compiler throws an error while converting an Object to String.
to
List<String> linhaInicial = new ArrayList<String>(); // using Generics ensures
//that your List can contain only Strings, so, compiler
//will not throw "incompatible types" error
Always try to include the type of the list element in your declaration:
List<String> linhaInicial = new ArrayList<String>();
Avoid raw types as much as possible.
You have to change
List linhaInicial = new ArrayList(); // you are using raw type List
To
List<String> linhaInicial = new ArrayList();// you have to use String type List

List-type explanation

Perhaps a bit misleading title, but not sure how to word it.
In the example of an ArrayList, what are the differences between these two list-objects:
ArrayList list = new ArrayList<Integer>();
and
ArrayList<Integer> list = new ArrayList();
Note: I know about the list hierarchy, interfaces and inheritance, but I am not sure how it applies in this situation. Can anyone please help me clear this up?
ArrayList list = new ArrayList<Integer>();
will give a warning about using the raw ArrayList object since you are not specifing the list is of a generic ArrayList type.
ArrayList<Integer> list = new ArrayList();
will give an unchecked conversion warning since you are assigning a non-generic ArrayList to a typed ArrayList
ArrayList<Integer> list = new ArrayList<>();
will work in java7+. The diamond operator tells the compiler to infer the generic type.
List<Integer> list = new ArrayList<Integer>();
is the standard way of using an ArrayList even it is more long winded than the new java7 syntax.

Java ArrayList declarations

I'm currently studying for the Java OCA exam and came across a question relating to ArrayList declarations.
Which of the following is valid?:
1. ArrayList al1 = new ArrayList();
2. ArrayList al2 = new ArrayList<>();
3. ArrayList<> al3 = new ArrayList<>();
4. ArrayList<Double> al4 = new ArrayList<>();
5. ArrayList<Double> al5 = new ArrayList<Float>();
According to my book, answers 1,2 and 4 are valid. Answers 3 and 5 are invalid.
However, no proper explanation is given. All it does is show the standard way to declare an ArrayList:
ArrayList<E> al3 = new ArrayList<E>();
and mentions that it's also valid to declare the ArrayList without the generic part.
I'm also unable to find a decent article on this topic online. Can someone explain (or point me in the direction of a good article) the different permutations above?
Thanks in advance.
1 is valid in all versions of Java
Here you are declaring the ArrayList without using Generics. This means regardless of what you add to the arraylist, when you get it back out it will be of type Object and will require casting to a type. This is the old way of using Collections in Java 1.4 (pre generics) and is supported for backwards compatibility. Nowadays you should always use Generics.
2 and 4 are valid in Java 7 only
The empty brackets: <> are Java7's new Type inference that means you don't have to specify the type twice. Note Java7, it wont work in older versions.
So in Java7
ArrayList<Double> al4 = new ArrayList<>();
Is the same as
ArrayList<Double> al4 = new ArrayList<Double>();
This link has more info on type inference: http://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html
3 is invalid because if you are using Generics you must specify a type in the variable declaration.
5 is invalid because if you declare a List with type Double you cannot then assign it a List that is of Type Float, you can only assign it a list of type Double.
So this would be valid:
ArrayList<Double> al5 = new ArrayList<Double>();
Below 2 will be valid only in Java SE7. Java SE7 allows type inference so you don't need to provide type inside <>again.
ArrayList<Double> al4 = new ArrayList<>();
ArrayList al2 = new ArrayList<>();
On the other hand below one is valid on all Java versions; this is to ensure backward compatibility of non-generic code.
ArrayList al1 = new ArrayList();
Below is not allowed as Collection of Float is not a sub type of collection of Double. Moreover Float is not subtype of Double; so no question of it being a valid declaration.
Note that even array version doesn't compile.
Double[] dd = new Float[5]; //won't compile
ArrayList<Double> al5 = new ArrayList<Float>(); //won't compile
Below one is not a valid declaration.
ArrayList<> al3 = new ArrayList<>();

Categories

Resources