Objectives Collection interface List interface ArrayList Differences between ArrayList and Vector ? Getting synchronized version of ArrayList object LinkedList
Introduction to Java Collections If we want to represent a group of objects as single entity then we should go for collections . A collection is an object that groups multiple elements into a single unit. Collections are used to store, retrieve and manipulate data. Collections framework in Java helps us in representing and manipulating collections. It is a collection of interfaces and classes which helps in storing and processing the data efficiently. Collections Framework standardizes the way we store and access the data from collections and is a part of the java.util package.
Differences between Arrays and Collections ? Arrays Collections 1) Arrays are fixed in size. 1) Collections are growable in nature. 2) Memory point of view arrays are not recommended to use. 2) Memory point of view collections are highly recommended to use. 3) Performance point of view arrays are recommended to use. 3) Performance point of view collections are not recommended to use. 4) Arrays can hold only homogeneous data type elements. 4) Collections can hold both homogeneous and heterogeneous elements. 5) There is no underlying data structure for arrays and hence there is no readymade method support. 5) Every collection class is implemented based on some standard data structure and hence readymade method support is available. 6) Arrays can hold both primitives and object types. 6) Collections can hold only objects but not primitives.
H ierarchy of the Java Collections framework.
The Collections hierarchy The following list describes the various interfaces of the collection framework: Collection - the root of the collection hierarchy A collection represents a group of objects known as its elements. Some types of collections allow duplicate elements and others do not. Some are ordered and others are unordered. Set - a collection that cannot contain duplicate elements List - an ordered collection Lists can contain duplicate elements. A programmer can access elements by their index(position) and has control over where each element is inserted in the list. Queue and Deque (pronounced as "Deck") - collections used to hold multiple elements prior to processing Besides basic collection operations, a Queue and a Deque provides additional insertion, extraction, and inspection operations. Queue Queues typically, but do not necessarily, order elements in a FIFO (first-in-first-out) manner. Among the exceptions are priority queues. In a FIFO queue, all new elements are inserted at the tail of the queue. Other kinds of queues may use different placement rules. Deque Deques can be used both as FIFO (first-in-first-out) and LIFO (last-in-first-out). In a Deque , elements can be inserted, retrieved and removed from both ends.
Collection: If we want to represent a group of "individual objects" as a single entity then we should go for collection. In general we can consider collection as root interface of entire collection framework. Collection interface defines the most common methods which can be applicable for any collection object. There is no concrete class which implements Collection interface directly
List: It is the child interface of Collection. If we want to represent a group of individual objects as a single entity where "duplicates are allow and insertion order must be preserved" then we should go for List interface
ArrayList Method Description
Add an item: The code below shows how to add food items to the ArrayList . food.add ("Noodles"); // Adding the elements food.add ("Burger"); food.add ("Pasta"); food.add ("Sandwich");
Modify an item: The code below shows how to modify a food item present in a specified index of the ArrayList . food.set (1, "Pizza"); // Modifying the element at a specified index
Check for an element: The code below checks whether the food item is present in the ArrayList or not. food.contains ("Pasta"); // Checking whether the element is present or not
Remove an item: Let us remove pasta from the ArrayList . Pasta is present at the second index position of the ArrayList . The position of the element to be removed should be specified in the method. food.remove (2); // Removing the element from the second index position
ArrayList Demo: import java.util.ArrayList ; import java.util.List ; class Tester { public static void main(String[] args ) { List<Integer> numbers = new ArrayList <Integer>(); // Creating an ArrayList object // Adding the elements to the list numbers .add (1); numbers .add (2); numbers .add (3); numbers .add (4); numbers .add (5); numbers .add (6); System. out .println ( "numbers list: " + numbers ); // Adding the number 15 at a particular index (index: 3) in the ArrayList numbers .add (3, 15); System. out .println ( "Observe the index position 3: " + numbers ); // Finding the size of the ArrayList System. out .println ( "Size of the ArrayList : " + numbers .size ()); // Retrieving the element at a specified index System. out .println ( "The number present at the fifth index position is " + numbers .get (5)); // Modifying the element at a specified index (index: 2) numbers .set (2, 200); System. out .println ( "The number at the 2nd index position is changed from 3 to 200" ); } }
Introduction to Generics: Let us now look at the declaration of the Collection interface . You can notice <T> in the declaration which you have not used before. The <T> syntax tells you that the interface is generic. public interface Collection<T> ... { }
Generic classes: Until 1.4v a non-generic version of ArrayList class is declared as follows. . add () method can take object as the argument and hence we can add any type of object to the ArrayList . Due to this we are not getting type safety. The return type of get() method is object hence at the time of retrieval compulsory we should perform type casting. class ArrayList { add(Object o); Object get( int index); }
Generic classes: But in 1.5v a generic version of ArrayList class is declared as follows . Based on our requirement T will be replaced with our provided type. For Example to hold only string type of objects we can create ArrayList object as follows. ArrayList <String > l=new ArrayList <String>();
Generic classes: But in 1.5v a generic version of ArrayList class is declared as follows . Based on our requirement T will be replaced with our provided type. For Example to hold only string type of objects we can create ArrayList object as follows. ArrayList <String > l=new ArrayList <String>();
Generic Types : Consider the following Container class . public class Container { private Object object ; public void set(Object object ) { this . object = object ; } public Object get() { return object ; } } This non-generic Container class operates on objects of any type. Since its methods accept or return an Object, you can pass whatever you want but there is no way to verify at compile time, how the class is being used. Someone may place an Integer in the container and expect to get Integers out of it, while someone else may pass in a String resulting in a runtime error.
Generic version of the Container Class A generic class is defined with the following format: class name<T1, T2, ..., Tn > { /* ... */ } The type parameter section, delimited by angle brackets (<>), follows the class name. It specifies the type parameters (also called type variables) T1, T2, ... and Tn. Container class can be updated with Generics as follows: public class Container<T> { // T stands for "Type" private T t ; public void set(T t ) { this . t = t ; } public T get() { return t ; } } As you can see, all occurrences of Objects are replaced by T. A type variable can be any non-primitive type you specify, any class type, any interface type, any array type or even another type variable
Generic version of the Container Class A generic class is defined with the following format: class name<T1, T2, ..., Tn > { /* ... */ } The type parameter section, delimited by angle brackets (<>), follows the class name. It specifies the type parameters (also called type variables) T1, T2, ... and Tn. Container class can be updated with Generics as follows: public class Container<T> { // T stands for "Type" private T t ; public void set(T t ) { this . t = t ; } public T get() { return t ; } } As you can see, all occurrences of Objects are replaced by T. A type variable can be any non-primitive type you specify, any class type, any interface type, any array type or even another type variable
Generic Methods In addition to generic types, type parameters can also be used to define generic methods. Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. You can create static and non-static generic methods and generic constructors. The syntax for a generic method includes a list of type parameters inside angle brackets which appears before the method's return type. public static <E> void method() { }
Generic Types - Tryout class Container<T> { private T t ; public void set(T t ) { this . t = t ; } public T get() { return t ; } } class Tester { public static void main(String[] args ) { Container<Integer> integerContainer = new Container<>(); integerContainer .set (1); // integerContainer.set (" Jeo ");//Uncomment the code and check if String can be passed to the set() method System. out .println ( "Inside Integer Container : " + integerContainer .get ()); Container<String> stringContainer = new Container<>(); // stringContainer.set (1); //Uncomment the code and check if Integer can be passed to the set() method stringContainer .set ( " Jeo " ); System. out .println ( "Inside String Container : " + stringContainer .get ()); } }
Generic Method - Tryout class GenericDemo { //Generic Method public static <E> void display(E[] arr ) { for (E element : arr ) { System. out .println ( element ); } } public static void main(String[] args ) { String[] names = { "Luke" , "Mia" , "Mathew" }; display( names ); System. out .println (); Integer[] numbers = { 1, 2, 3, 4, 5 }; display( numbers ); } }
ArrayList - Tryout 1 import java.util.ArrayList ; // Importing the ArrayList class import java.util.List ; class Tester { public static void main(String[] args ) { List<String> food = new ArrayList <String>(); // Creating a list of String elements food .add ( "Pizza" ); // Adding elements food .add ( "Burger" ); food .add ( "Pasta" ); food .add ( "Sandwich" ); System. out .println ( "Food items: " + food ); } }
ArrayList - Tryout 2 import java.util.ArrayList ; import java.util.List ; class Tester { public static void main(String[] args ) { List<Integer> numbers = new ArrayList <Integer>(); // Creating an ArrayList object // Adding the elements to the list numbers .add (1); numbers .add (2); numbers .add (3); numbers .add (4); numbers .add (5); numbers .add (6); System. out .println ( "numbers list: " + numbers ); // Adding the number 15 at a particular index (index: 3) in the ArrayList numbers .add (3, 15); System. out .println ( "Observe the index position 3: " + numbers ); // Finding the size of the ArrayList System. out .println ( "Size of the ArrayList : " + numbers .size ()); // Retrieving the element at a specified index System. out .println ( "The number present at the fifth index position is " + numbers .get (5)); // Modifying the element at a specified index (index: 2) numbers .set (2, 200); System. out .println ( "The number at the 2nd index position is changed from 3 to 200" ); } }
Iterating through ArrayList using for-each - Tryout import java.util.ArrayList ; import java.util.List ; class Student { private int studentId ; private String studentName ; private boolean courseRegistered ; public Student( int studentId , String studentName , boolean courseRegistered ) { this . studentId = studentId ; this . studentName = studentName ; this . courseRegistered = courseRegistered ; } public int getStudentId () { return studentId ; } public void setStudentId ( int studentId ) { this . studentId = studentId ; } public String getStudentName () { return studentName ; } public void setStudentName (String studentName ) { this . studentName = studentName ; } public boolean getCourseRegistered () { return courseRegistered ; } public void setCourseRegistered ( boolean courseRegistered ) { this . courseRegistered = courseRegistered ; } } class Tester { public static void main(String[] args ) { List<Student> students = new ArrayList <Student>(); students .add ( new Student(1001, "Steve" , true )); students .add ( new Student(1002, "Rachel" , false )); students .add ( new Student(1003, "Monica" , true )); students .add ( new Student(1004, "David" , true )); List<String> studentNames = new ArrayList <String>(); for (Student student : students ) { studentNames .add ( student .getStudentName ()); System. out .println ( "Student Id: " + student .getStudentId ()); System. out .println ( "Student Name: " + student .getStudentName ()); System. out .println ( "Course Registered: " + student .getCourseRegistered ()); } System. out .println ( "===========================================" ); System. out .println ( "Student Names: " + studentNames ); } }