<E> and <Object> differences and usage - java

Can someone explain me what are the differences by using E or Object for example in a class for Lists, and their singular usage and definition.
I have to use them in LinkedLists to implement methods.

Assuming that E comes from element, i would consider using generics in Collections when the method that compiles says that it took an array of a certain type, and returns an array of the same type.
On the other hand you can't mix oranges and apples. You would be able to add an Object to your String list if you could pass a string list to a method that expects object lists. (And not all objects are strings)

The syntax you've written as <E> refers to Generics.
Generics provide a way to re-use the same code generalized for different data types while still maintaining strict type checks at compile time. For example, as you mentioned, If you'd use a data structure handling elements of type Object, you wouldn't have type safety when adding or getting its elements because any class instance could be passed and retrieved from it. This would lead to error-prone code where elements retrieved from your data structure should be cast first to the expected data type in order to be used or in the worst scenario not being of the right type and knowing this only at run-time with no way to prevent it.
Because of this, Generics aid the developer allowing him/her to establish for each different situation the generic Type Parameter with a specific Type Argument (a non-primitive type). This not only provides much more flexibility and re-usability of your code, but once you've established that a generic Type Parameter E stands for a specific data type (Integer, String or other), then the compiler will make sure that every operation that your object will perform with the Type Parameter E will be compliant with the specific Type Argument you've put in place of E.
public class Test {
public static void main(String[] args) {
//Here I can add mixed non-primitive types because they're also instances of Object and therefor compliant to the expected type
List listObj = new ArrayList();
listObj.add(Integer.valueOf(5));
listObj.add("Hello");
listObj.add(Double.valueOf(3.77));
//Here I can't retrieve the elements with their right type even though I know I've placed an Integer, a String and a Double in its first, second and third position
Integer i1 = listObj.get(0);
String s1 = listObj.get(1);
Double d1 = listObj.get(2);
//Here I'm defining a generic list working only with Integer (for this specific instance)
List<Integer> listGenInt = new ArrayList<>();
listGenInt.add(Integer.valueOf(5));
//If I try to add any other type but Integer I'd get an error at compile time
listGenInt.add("Hello");
listGenInt.add(Double.valueOf(3.77));
//Here I can only expect to retrieve elements of the data type I've established for this object during its declaration (Integer)
Integer i2 = listGenInt.get(0);
//Here I'd get an error If I'd try read its elements with any data type but Integer
String s2 = listGenInt.get(1);
Double d2 = listGenInt.get(2);
//Here I'm defining a generic list working only with String (for this specific instance)
List<String> listGenStr = new ArrayList<>();
listGenStr.add("Hello");
//If I try to add any other type but String I'd get an error at compile time
listGenStr.add(Integer.valueOf(5));
listGenStr.add(Double.valueOf(3.77));
//Here I can only expect to retrieve elements of the data type I've established for this object during its declaration (String)
String s3 = listGenStr.get(1);
//Here I'd get an error If I'd try read its elements with any data type but String
Integer i3 = listGenStr.get(0);
Double d3 = listGenStr.get(2);
}
}
Here, there is also a link with examples and further explanations from the official tutorials by Oracle.
https://docs.oracle.com/javase/tutorial/extra/generics/intro.html

Related

ArrayList Generic without Type

recently I read a piece of code which seems weird to me. As we know, we need to initialize the generic type in collections when we need to use them. Also, we know Collections can contain Collections as their elements.
The code:
public class Solution {
public static void main(String args[]) {
ArrayList res = returnlist();
System.out.print(res.get(0));
}
public static ArrayList<ArrayList<Integer>> returnlist() {
ArrayList result = new ArrayList();
ArrayList<Integer> content = new ArrayList<Integer>();
content.add(1);
result.add(content);
return result;
}}
My question is
why can we use ArrayList result = new ArrayList(); to create an object, since we have not gave the collection the actual type of element.
why can we use result.add(content); to add a collection to a collection with collection "result" is just a plain collection. We have not defined it as a ArrayList of ArrayList
Java generic collections are not stored with a type to ensure backwards compatibility with pre J2SE 5.0. Type information is removed when added to a generic collection. This is called Type Erasure.
This means that a generic collection can be assigned to a non generic reference and objects in a generic typed collection can be placed in an non generic, nontyped collection.
All Java generics really does is make sure you can't add the wrong type to a generic list and saves you from doing an explicit cast on retrieval; even though it is still done implicitly.
Further to this
the Java section of this answer goes a little deeper into what I just said
this article also covers basically what you were asking in a more complete way
other things to watch out for with Type Erasure
Just adding up to provide summarized answer
Old way :
(A) ArrayList result = new ArrayList();
will create an Arraylist to hold "Object"
New Way :
ArrayList<Integer> content = new ArrayList<Integer>();
this represents an Arraylist which will hold "Integer" objects. This was introduced for compile-time type check purposes.
why ?
Consider the first case. Its input type is Object. We know that Object is the super class of all classes. We can pass in an Integer object, String object and so on. When fetching the data the developer has to perform proper type casting. Say if the developer initially thinks the code will accept Integer objects so he adds the following typecast while fetching the data
Integer integer=(Integer) content.get(0);
This is supposed to work. But if mistakenly he passes a String it will result in run-time error.
How it can be avoided ?
By introducing compile time checks
How it works ?
when we specify parameterized type only Integer objects can be added to the ArrayList collection. Else it will show error.
content.add(3); // will work
content.add("HARSHAD"); // error shown
If parameterized generic types are for type checking purposes how correct data can be retrieved from the list ?
The compiler implicitly performs type conversion. See the sample code
List<Integer> list=new ArrayList<Integer>();
list.add(1);
list.add(2);
Integer integer=list.get(0);
System.out.println(integer);
What the compiler actually does when you perform compilation ?
//perform type erasure
(B) List list=new ArrayList();
list.add(1);
list.add(2);
// the arraylist inturn accepts Object when you run the code
//add casting
Integer integer=(Integer)list.get(0);
Conclusion
If you see the codes (A) and (B) both are the same. Only difference is that in the second case the compiler implicitly does the same operation.
Finally to answer your question ...
ArrayList result = new ArrayList();
is allowed for backward compatibility purposes. Although this is not recommended.
Official link from Oracle docs explaining the same concept.
Generics were added to Java only in Java 5. Before that, when you use a collection, it always meant collection of objects. The old syntax is left as is for backward compatibility. So ArrayList result = new ArrayList() is actually creating an ArrayList<Object>. Since ArrayList is also an object, you can add content to the variable result.
why can we use ArrayList result = new ArrayList(); to create an object, since we have not give the collection the actual type of element.
Because java wants to it backward compatible. Generics is more of compiler feature for ensure type safety, collections can store any type of object at runtime.
Java compiler will not give you compiler error for this but it must have given you compiler warning that it is unsafe to use generic classes without type.
It may be a remnant from before generics came along to java (Java 4 or 5 I think).

A Java ArrayList Qusetion

Question: If you have a List and it has String objects, which declaration(s) of your List does not require that objects retrieved using the get method be cast to Strings, before calling a String method? List <Object> a = new ArrayList <Object>();
I. List<Object> a = new ArrayList <Object>();
II. List<String> a = new ArrayList <String>();
III.List a = new ArrayList();
I don't really understand this question. I think you must cast to a String to use it as a String, then it must be a declaration that does not return a String object as a String.
Here's how you should think about the answer: What does each of the following return?
I. and III. are the same thing. Both instances will return a java.lang.Object if you call get. You'll have to cast that to a java.lang.String in order to use it.
Only II. will return a String if you call get, because of the generic declaration.
2 will not require explicit casting. 1 and 3 are effectively the same thing.
The second one.
ArrayList<String> a = new ArrayList <String>();
This means that the arraylist can only hold string type variables. It says string in the pointy brackets. This is called generics and it allows the data you take out to be of the form you specify, in this case a String.
I. and III both are a list of Objects (and I. has a typo on the declaration, the correct class type is "Object"). You can store anything in them, including Strings, but as far as the compiler can tell... they're of type Object, so if you want to call a String method on an object you retrieved with the ArrayList.get(...) method you will have to cast the returned object to String.
II. is a list of Strings (the type of stored objects is specified by the generics part between <...>), the compiler knows the ArrayList will only store Strings, so the ArrayList.get() will return a String directly, without the need for a cast.
You can see an example of this exact thing in the Java Generics Tutorial.

What is the error Java ArrayLists

I am throughly convinced that this is snippet of code has an error. The Java from the ground up programming book says that there is no error. This is the code:
ArrayList temp = new ArrayList();
temp.add("35");
temp.add(35);
Isn't there an error with line 2? An arrayList cannot have a string and an integer within the same ArrayList correct? Please correct me if I am wrong, I have a test on this tomorrow. Thank you all in advance!
Yes, it is correct.
Since you haven't declared any type in ArrayList it allow all Objects.
Now your ArrayList as same as
ArrayList<Object> temp = new ArrayList<Object>();
And see below examples
ArrayList<String> temp = new ArrayList<String>();
temp.add("35");
temp.add(35); //compiler error, Only Strings please
see below example
ArrayList<Integer> temp = new ArrayList<Integer>();
temp.add("35");//compiler error, Only Integers please
temp.add(35);
And it's highly discouraged to use Raw types, Always prefer to use with specific type.
Now in first case ArrayList temp = new ArrayList();, when you return it returns an Object which is unkown type. It may be an Integer or a String, you need to check it manually after you got it back from List
ArrayList temp = new ArrayList(); There is no issue here. This is an ArrayList which will accept any data type since it is not defined specific data type (raw ArrayList).
it is correct because its a raw type means you can add any object.You can add anything that extends Object class
you can write temp.add(x); where x can be any thing String,int,long Date anything that extends Object
example
String x="";
int x1=1;
Date df=new Date();
temp.add(x);// will work
temp.add(x1);//will work
temp.add(df);// will work
yes your array list can hold both String and integer.
but array list only store objects String and Integer objects it doesnt support int primitive datatypes only objects inside arraylist
ArrayList<Object> arr=new ArrayList<>();
String s="35";
Integer in=35;
arr.add(in);
arr.add(s);`
It is correct. Since you haven't declare any type for list, it treats all the elements as Object class. Your definition is
ArrayList<Object> arr=new ArrayList<>();
for compiler. In this case 35 will be boxed to Integer and "35" will be a String. Both Integer and String are subclass of Object and there wan't be any compile time error.
In java there is something named as Generics which allows programmers to abstract over types.
Arraylist code internally uses it.So when you don't define any generic type the default type it takes is the Object class type.
And as String as well as Integer both are subclasses of Object class, so this operation is allowed according to OOPs.

Interpreting JAVA Command

I am in a data structures class and have had about a year and half of experience with JAVA. I am trying to understand code which is not clearly defined in the book. In the following line:
Queue<Integer> encodingQueue = new LinkedList<Integer>();
I understand that we are creating a new LinkedList object of Queue type. My questions are:
what is the <> used with Integer for? And why is it also with the LinkedList object and not in the parameters?
Why is the word Integer used and not int?
Thanks!
good luck in your data structures class!
Generics
In Java, these data structures (i.e. Queue, LinkedList, ...) can hold any kind of object. More often than not, though, a given instance of a Queue or LinkedList will hold a collection of the same type (here integers).
The angle-bracket syntax is used to specify which types are allowed in this specific instance of the collection.
So, the way to read:
Queue<Integer> encodingQueue = new LinkedList<Integer>();
is...
"Create a new linked-list that holds only integers, and assign that instance to the reference variable 'encodingQueue' which will be treated like a queue that holds only integers."
This feature that you're using is called "Generics". You can read up more about it here: http://en.wikipedia.org/wiki/Generics_in_Java
Autoboxing
In Java, there are two kinds of types: primitives and object references. "int" is a primitive and "Integer" is a class.
You cannot create a reference to a primitive in Java and collections (like LinkedList) only hold object references. So, you cannot stuff a primitive into a collection (e.g. you cannot put "int"s into a LinkedList). This is why Java provides the object equivalent for primitives: so that you can create collections of things like integers, floats, booleans, etc.
It can be a little confusing when you first start using primitives; Java will attempt to automatically convert primitives to object references when that's what's clearly needed (and vice-versa). This feature is called "autoboxing".
List myList = new LinkedList<Integer>();
myList.add(2);
Here, 2 is a primitive. But the compiler knows that you need an object reference, not a primitive. So, it automatically "boxes-up" this value by (in the background) creating a new instance of the class Integer and setting it's value to 2.
So, that's equivalent to (and this is what actually happens):
List myList = new LinkedList<Integer>();
myList.add(Integer.valueOf(2));
Where Integer.valueOf() first looks in an internal cache to see if an instance already exists for that value. If it does, that's returned, otherwise a new Integer object for that value is created. (Thank you, Boris, for pointing this out)
http://docs.oracle.com/javase/tutorial/java/generics/
Used to specify type parameters. It's how you pass a type into a class. Lists/queues have them, because it's the type of Object that the list holds.
Integer is used instead of int because ints are not Objects. Integer is just the wrapper class for it.
Integer is a object based wrapper version of the primitive 'int'. This allows the basic type to play well in object oriented language. Read more here:
They can be used interchangably native and wrapper, this is called 'autoboxing/unboxing'
http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html
The <> are part of Java Generics (A way to tell the compiler what object you expect to work with), more here:
http://docs.oracle.com/javase/tutorial/java/generics/
Happy learning!
That infers the type of object to be stored in the Queue. You'll want to look into Java Generics.
Collections store objects, int is a primitive type, Integer is the Java object representation. The compiler will autobox any ints you attempt to put in the Queue as Integers.
1) <Integer> is used to specify at compile-time that the objects contained in your Collection are going to be Integers, so for instance this will not compile:
Double d = 10d;
encodingQueue.add(d); <-- Compilation error
2) The reason why Integer is used instead of int is that you cannot store into collections primitive data types but you have to use objects; you can still write encodingQueue.add(10) thanks to the automatic boxing of ints inside Integers, but when you declare a typed collection (or, in general, a parameterized class) you have to use a class that extends Object as the parameter.
the <Integer> specifies the type of the data that the object is going to hold. it is Integer instead of int because the LinkedList is designed to hold an Object and not a primitive. so
Queue<Integer> q = new LinkedList<Integer>();
means that we are creating an Object of LinkedList that holds Integer type objects and we are refering it with a Queue reference variable.
what is the <> used with Integer for? And why is it also with the
LinkedList object and not in the parameters?
If you have a Parameterized Collection Queue<Integer> than a Raw type Queue
it ensures that none of the Objects other than Integer are added in the Collection.
This feature was introduced from Java 1.5
Why is the word Integer used and not int?.
Collection deals with Objects and not primitives.
Consider this example from Effective Java Item 23
// Now a raw collection type - don't do this!
/**
* My stamp collection. Contains only Stamp instances.
*/
private final Collection stamps = ... ;
If you accidentally put a coin into your stamp collection, the
erroneous insertion compiles and runs without error:
// Erroneous insertion of coin into stamp collection
stamps.add(new Coin( ... ));
You don’t get an error until you retrieve the coin from the stamp
collection:
// Now a raw iterator type - don't do this!
for (Iterator i = stamps.iterator(); i.hasNext(); ) {
Stamp s = (Stamp) i.next(); // Throws ClassCastException
... // Do something with the stamp
}
Example with Parameterized
// Parameterized collection type - typesafe
private final Collection<Stamp> stamps = ... ;
From this declaration the compiler knows that stamps should contain
only Stamp instances and guarantees this to be the case, assuming your
entire code base is compiled with a compiler from release 1.5 or
later and all the code compiles with- out emitting (or suppressing;
see Item 24) any warnings. When stamps is declared with a
parameterized type, the erroneous insertion generates a compile-time
error message that tells you exactly what is wrong:
Test.java:9: add(Stamp) in Collection<Stamp> cannot be applied to (Coin)
stamps.add(new Coin());
They are a type of generic (see #JTigger's answer) this means they can be a queue/list of ANY Java object including custom Java objects, this allows you to use the queue/list functions on anything inside of Java without reinventing the wheel.
Example:
Say we have the custom Object "planet":
public Class Planet {
private String name;
public Planet(String name) { this.name = name; }
public String getName() { return name; }
}
and we want to put a list of planets inside a queue. We could create said queue, and use the already built add() and remove() methods. If Queue was not a Generic class we would have to build our own add() and remove() functions. So using Generics we can list all the names of the planets in the solar system:
public static void main (String args[]) {
Queue<Planet> solarSystem = new LinkedList<Planet>();
solarSystem.add(new Planet("Mercury"));
solarSystem.add(new Planet("Venus"));
solarSystem.add(new Planet("Earth"));
solarSystem.add(new Planet("Mars"));
solarSystem.add(new Planet("Jupiter"));
solarSystem.add(new Planet("Saturn"));
solarSystem.add(new Planet("Uranus"));
solarSystem.add(new Planet("Neptune"));
solarSystem.add(new Planet("Pluto")); //For Nostalgia's sake
for (int i = 0; i < 9; i++) {
System.out.println(solarSystem.element().getName());
solarSystem.remove();
}
}

what is this mean in the ArrayList in Java

I'm new in Java, and I have seen a ArrayList example like this.
listing = new ArrayList<Lot>();
I know that if I want to create an empty array list. Then I will use ArrayList()
But I don't understand what is the <Lot> between the "ArrayList" and "()".
Can someone explain it to me?
Thanks
This is Java Generics. The <Lot> indicates that the ArrayList will contain only objects of type Lot. It is useful because the compiler can do type checking on your ArrayList.
It is called as type parameter. It denotes that ArrayList will only contain objects of type Lot
Check out concept of Generics.
You will get the use of this ArrayList<Lot> with this example :
// (a)Without Generics ....
List myIntList = new ArrayList(); // 1
myIntList.add(new Lot(0)); // 2
Lot x = (Lot) myIntList.iterator().next(); // 3
// (b)With Generics ....
List<Lot> myIntList = new ArrayList<Lot>(); // 1’
myIntList.add(new Lot(0)); // 2’
Lot x = myIntList.iterator().next(); // 3
Two points to be noted in the above e.g
In e.g(b), Since we already specified that ArrayList will contain only objects of type Lot, in Line 3, we didn't have to perform casting it to type object Lot. This is because the compiler already know that it will have only Lot type of objects.
Trying to add any other type of object to e.g (b) will result in compile time error. This is because the compiler has already identified this List is specific to contain elements of only type Lot. This is called type checking
It is an extension to Java's type system called, Generics.
Generics allow you to create a List that contains a specific sub-type of Objects (or a specific set of Objects that implement particular interfaces, instead of a collection that only holds plain Objects.
listing = new ArrayList<Lot>();
this line just says that the type of objects to be inserted,updated,retrieved in or from ArrayList are of the type Lot.
This is what is called the generics in java.
Using the generics type casting is not required at the time of retrieval of objects from any List.

Categories