This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 2 years ago.
What's the difference between the following lines:
ArrayList list = new ArrayList();
ArrayList<String> list = new ArrayList();
ArrayList<String> list = new ArrayList<String>();
I just started learning about collections and data structures from the HeadFirstJava book and am a bit confused since I see people use all three of the examples above while researching.
The first and second line use raw types.
A raw type is a type that is used without type parameters, even though the base class has a type argument.
Raw types exist only for backwards compatibility with ancient (pre-Java 5) code and should never be used in new code at all. The rules about raw types are weird and unintuitive.
The third one is correct, but can be written in a shorter way like this:
ArrayList<String> list = new ArrayList<>();
This one will let the compiler "guess" what is meant to go into the <>.
Related
This question already has answers here:
Java Raw Type and generics interaction
(2 answers)
Closed 6 years ago.
What is the difference between
List<String> list = new ArrayList();
and
List<String> list = new ArrayList<>();
?
In the first case, the IDE highlights it and says "Unchecked assignment", but they seem to behave exactly the same.
The type of each entry in the ArrayList has not been specified, only the List, hence why the Unchecked assignment warning. You should explicitly state it in one of two ways...
List<String> list = new ArrayList<String>();
Or, you can abbreviate that now (since Java 7) to...
List<String> list = new ArrayList<>();
...and the compiler will then be able to implicitly pick up the type from the List's type designation.
No difference, java compiler could figure out the type, but better add the inferred type argument:
List<String> list = new ArrayList<String>();
This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 7 years ago.
I can't understand the difference between the two code snippets below. Can someone help me with a simple explanation?
When we should use them?
If someone can help me with a simple explanation I'll appreciate.
//1
List list1=new ArrayList();
for(Object obj:list1){}
//2
List<Object>list2=new ArrayList();
for(Object obj:list2){}
Generics comes with Java5 and the main idea of this is to avoid the well know exception ClassCastException. In your example, before Java5 we were used to iterate collections of object and casting it's on runtime, so the exception mentioned above happened very often.
With Generics this kind of runtime exception became a compile time exception and you are be able to realized these errors early. In your example you can choice if you want to handle this situation as a runtime error (option 1) or compilation error (option 2) and realize how easier is to handle it in the option 2.
Generics is more than just implicit or explicit declaration, you should take a look at this tutorial.
List and List<Object> are similar (in that you can add any type to them) but different things .
List is a raw type and i can say List l =new ArrayList<Integer>() or List l =new ArrayList().
But for List<Object> ,i can only assign List implementation of Object type. I can't say List<Object> l = new ArrayList<Integer>(); .
This question already has answers here:
"Program to an interface". What does it mean? [duplicate]
(8 answers)
Closed 8 years ago.
In this statement List<String> MyList = new ArrayList<String>();
Why declare Mylist as a List of type String. just to make MyList a new instance of an ArrayList type String?
It seems unnecessary.
To paraphrase Item 52 of Joshua Bloch's Effective Java, using the interface instead of the class makes the surrounding code much more flexible. So if you wanted to change myList to something like a Vector, you wouldn't have to change the surrounding code much if at all. Bloch goes on to say that there are certain times, such as major updates to java, when other types of Lists are updated for effectiveness or new ones are added entirely.
Declaring MyList as type List<String> guarantees that you won't use methods only available for ArrayList<String>. That way, you can change the right-hand side of the declaration in the future.
List is just an Interface, not an implementation. There are many different types of lists, such as ArrayList and LinkedList.
So if you declare MyList an List<String> it could possibly be any type of List, as #espertus said, you can change what type of list MyList is in the future without having to change it's declaration.
This question already has answers here:
Is it possible to use a primitive type (int) in as a generic type in Java?
(2 answers)
Closed 9 years ago.
Im trying to defined a generic LinkedList of type int but it throws me a compile errror
List<int> I = new LinkedList<int>();
You have to use wrapper classes to do that.
List<Integer> I = new LinkedList<Integer>();
You can insert an int in this linked list as autoboxing will automatically create a Integer object out of this int and add it to the LinkedList.
You can't use a primitive type as a generic type. If you really want to do that, that's what the wrapper classes (Integer, Float, etc.) are for. You can do it like this:
List<Integer> I = new LinkedList<Integer>();
You will still be able to put ints in the list because of autoboxing. If you try to use an int in a situation that requires an Integer, a new Integer will automatically be created with Integer.valueOf and used instead.
Also, in Java 7, you can use the diamond operator and just use this:
List<Integer> I = new LinkedList<>();
There is no advantage to this, except it is faster to type.
This is one reason Java has primitive wrapper classes, since you can't use primitives as type arguments. In your case, you need Integer:
List<Integer> I = new LinkedList<Integer>();
In Java 7+ you don't need to reiterate the type parameter:
List<Integer> I = new LinkedList<>();
See also: Generics
This question already has answers here:
What's the difference between unbounded wildcard type List<?> and raw type List?
(4 answers)
Closed 4 years ago.
I've read alot about this, and I know that:
List<Object> listOfObject = new ArrayList<TYPE>(); // (0)
//can only work for TYPE == Object.
//if TYPE extends Object (and thus objects of type TYPE are Objects),
//this is not the same with Lists: List<Type> is not a List<Object>
Now I've read that the following is ok:
List undefinedList = new ArrayList<TYPE>(); // (1)
//works for ANY type (except for primitives)
And
List<?> wildcardList = new ArrayList<TYPE>(); // (2)
//also works for ANY type (except for primitives)
Then:
List undefinedlist = new ArrayList(); //no TYPE specified
undefinedList.add(new Integer(1)); //WORKS
undefinedList.add(new String("string")); //WORKS
However:
List<?> wildcardList = new ArrayList<TYPE>(); //TYPE specified
wildcardList.add(new TYPE(...)); //COMPILER ERROR
example:
List<?> wildcardList = new ArrayList<String>(); //TYPE specified
wildcardList.add(new String("string")); //COMPILER ERROR: The method add(capture#1-of ?) in the type List<capture#1-of ?> is not applicable for the arguments (String)
I do understand why you can't add anything to the wildcardList, since its type can be anything. However, why can you add to the undefinedList??
They seem the same & show the same behavior, given (1) and (2).
List undefinedList and List<?> wildcardList are not the same, as you discovered yourself. The first is raw type and the second is unbounded wildcard.
Use the unbounded wildcard if you want to use a generic type but you don’t know or care what the actual type parameter is. You cannot put anything (except null) into this list, and all you know about the element you get out of it is that they extend Object (actually List<?> is the same as List<? extends Object>). Unbounded wildcards are useful, because if you would declare something naively as List<Object>, you could not assign for example List<String> to it, while you can assign a List<String> to a List<?>
You should (almost) never have the need to use raw types, they are available only for compatibility with code written before Java 5.
List<?> is read as a list of some unknown type . As a programmer you can not make any assumption of what type that is and you can not put anything into such a collection other than null . But you can be rest assured that your list is type safe since the compiler will guarantee type safety for you .
List is basically called raw type . That is to say that it has opted out of type safety guaranteed by the compiler . So you can put elements of any type into that List destroying its invariants . Don't code with raw types any more . They are basically supported for backward compatibility because java was already in the second decade of development when Sun brought generics to the table and a awful lot of code was written using raw types and those programs would otherwise break.
List means that this is a list of unknown type - as such you wouldnt use it at creation time (as in your example), you'd typically use it as a method parameter. Unbound wildcards are only really useful when used as parameters in methods, such as:
public void printList(List<?> items)
This could iterate of a list of (any) unknown items. In this case List items would achieve the same purpose, but client would probably get a warning.
If you had the following:
public void printList(List<Object> items)
Then only a list of Object could be processed - not a list Strings, Integers etc. Only Objects.
Take a look at Unbounded Wildcards - it explains its pretty well
The "undefined" List contain list of type Object which is the father of all types and hence the List is not type-safe(is interconvertible)
which is why this:
List undefinedlist = new ArrayList<TYPE>(); //IS LIST OF OBJECTS
undefinedList.add(new Integer(1)); //WORKS
undefinedList.add(new String("string")); //WORKS
well.. works!
Basically, ? in the following
List<?> wildcardList = new ArrayList<TYPE>();
means some unknown (particular) type. So, it doesn't allow you add something like String, or Integer to a list of some unknown type, because generics is meant to be type-safe.
While, in the following
List<Object> listOfObject = new ArrayList<TYPE>();
you can add anything to it because everything is an Object in Java. So it's type-safe.
And also with the following
List undefinedList = new ArrayList<TYPE>();
you are telling the compiler that you don't want to use generics there. Which means every method you invoke on undefinedList will be non-generic since you have decided to use the raw List. Non-generic versions of all the containers in the collection framework were written to work for Object (which any object in Java is).
The List<?> type is generic: whatever type you put in place of the question mark will be used in the methods of the list. So you can do list.add(item) and it will only allow you to put in a String if you created a List<String>. Type-safety first.
List<String> list = new List<String>();
list.add("A"); // <-- Correct
list.add((Integer)10); // <-- Error, it is a List of Strings
The List on the other hand allows any Object to be put in there. So you can make a List, put a Giraffe in there, and later a Squid. It does not care, and could be a source of programming errors if you expect only Giraffe objects to be in there.
List list = new List();
list.add("A"); // <-- Allowed
list.add((Integer)10); // <-- Also allowed,
// but now the list contains not only strings