Can someone explain to me what this code is doing, I am new to java.
Queue <TreeNode> queue = new LinkedList<TreeNode>();
I believe this code creates a Queue with the variable name queue that is of type TreeNode, what does the right side mean? Is it assigning the Queue to be a Linked List of type TreeNode?
Class java.util.Queue uses type parameters to assure that you won't add type other than it was created with.
If you create Queue like:
Queue <TreeNode> queue = new LinkedList<TreeNode>();
It means queue can store only TreeNode objects. This is used for type checking in methods add,offer,remove,poll.
Yes to understand this you must have at least little understanding of generics in java. The generics are very important feature of java and java collection framework use this feature in full form. Let me describe your statement given below.
Queue <TreeNode> queue = new LinkedList<TreeNode>();
Here First thing to be notice is that almost all collection classes and interface are generic in nature. That means they can store any type of data in them. See the below example.
List list = new ArrayList();
String sObj = "stringObj";
Integer iObj = 1;
MainTest classObj = new MainTest();
list.add(sObj); //Storing string
list.add(iObj); // Stroing int
list.add(classObj); //Storing class object
Here you can see that i have created a ArrayList and referenced it through a List reference variable. Here you can notice this i have not metioned any class here so by default it will store all object types of objects. Now if we come to your code that means you are restricting the collection to store only one type of objects which is TreeaNode .So that any other type of object will be added in this collection any more. In you statement in left side you are Creating a reference variable with name queue whose data type is Queue of TreeNode while on right side you are assigning a object of LinkedList which can store only TreeNode objects int to you queue reference variable.That means you queue will not be allowed to add any object in it excluding TreeNode. This assignment is possible both classes Queue and LinkedList implements Collection interface.
The link below describes what a generic is in Java and why they are used.
https://docs.oracle.com/javase/tutorial/java/generics/why.html
By Using generics we make sure the type safety of our objects.
In your question
Queue <TreeNode> queue = new LinkedList<TreeNode>();
you have created queue with generic type "TreeNode". So it'll allow only those objects which will instanceOf "TreeNode" class.
A Generic allows you to specify what type of reference a DataStructure will store. In your example the List will variables of type TreeNode.
But you can store any type, including your own user defined types such as classes.
Related
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
I just wanted to clarify this question I had for a while for more efficient and 'correct' code.
I gave a class 'Student' with objects in an array list of objects. I have another class called Class which has an array list of references to the very same objects in the Student class.
Should I declare the 'Class' class as
ArrayList<Student> myStudents = new ArrayList<Student>();
or
ArrayList<Class> myStudents = new ArrayList<Class>();
Also another part of the question is I have seen people declare arrayLists as ArrayList<Student> myStudents = new ArrayList<>();
where the second half of the carrots are left empty. What exactly does the difference mean? Does this mean that the array list is not an object of any class?
Thank you so much for your time and help
Cheers
It depends on what you want to store in the list rather than where you are using it. If you're storing Student objects, then you'll use ArrayList<Student>().
The type omitted on the right side is called type inference (added in java 7), which means the type parameter on the right side will be inferred from the type of the assignment variable on the left. It helps to write the code in a cleaner way. For e.g.
Writing below is easier:
List<Some<Type<Another>>> var = new ArrayList<>();
than:
List<Some<Type<Another>>> var = new ArrayList<Some<Type<Another>>>();
Technically, neither.
You would want to do:
List<Student> myStudents = new ArrayList<>();
if you want to create an ArrayList with Student objects and
List<Class> myClasses = new ArrayList<>();
if you want to create an ArrayList with Class objects.
1) Note the variable names.
2) Note that you should always try to code to an interface (the left side is a List, not an ArrayList). This allows much greater flexibility since you're not dependent on the specific implementation of an ArrayList later on. This point is so powerful! You can write method signatures to accept objects of type List and then use an ArrayList, LinkedList or Stack or any class that implements a List. Depending on how you are using your ArrayList later, the Collection interface may be sufficient instead.
The diamond operator allows the compiler to infer the value of the type argument without having to type it all out. It's needed for backward compatibility for older Java versions.
As a general practice for performance optimization, you will also want to supply an initial capacity of an ArrayList if it's possible. So if you know that there are only 5 classes, then you would do:
List<Class> myClasses = new ArrayList<>(5);
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 the difference when creating these two objects
Queue<String> test = new LinkedList<String>();
and
List<String> test2 = new LinkedList<String>();
What are the actual differences between test and test2? Are both of them LinkedList ? Are there performance differences or reasons to use one over the other?
The two statements you've written each construct a LinkedList<String> object to hold a list of strings, then assign it to a variable. The difference is in the type of the variable.
By assigning the LinkedList<String> to a variable of type Queue<String>, you can only access the methods in the LinkedList that are available in the Queue<String> interface, which includes support for enqueuing and dequeuing elements. This would be useful if you needed to write a program that used a queue for various operations and wanted to implement that queue by using a linked list.
By assigning the LinkedList<String> to a variable of type List<String>, you can only access the methods in the LinkedList that are available in the List<String> interface, which are normal operations for maintaining a sequence of elements. This would be useful, for example, if you needed to process a list of elements that could grow and shrink anywhere.
In short, the two lines create the same object but intend to use them in different ways. One says that it needs a queue backed by a linked list, while the other says that it needs a general sequence of elements backed by a linked list.
Hope this helps!
In the both the cases, you are instantiating LinkedList.
The difference is the types of the variables you use to refer to those instances.
test is of type Queue and test2 is of type List. Depending on the type of variable, you only get to invoke the methods which are specified on that particular type. I think this what matters for your situation.
Performance-wise, it's going to be the same, because the actual implementation that you are using in both the cases is same (LinkedList).
I feel both of them are pretty much same except that the type of methods you are going to expose. As LinkedList implements both the interfaces, so choosing one of them opens up access to methods of that interface type.
please take a look at these links for interface method declarations
http://docs.oracle.com/javase/6/docs/api/java/util/Queue.html
http://docs.oracle.com/javase/6/docs/api/java/util/List.html
i am not sure about the performance, though i guess it shouldn't be different as the object implementation is common.
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.