The collection framework in java is made up of classes and interfaces that stores and processes data in an efficient manner.
The Sun Microsystems has introduced collection framework in Java 2.0
The hierarchy of the whole collection framework is given below :
List is an interface that is available in the java.util package.
List is used to store a collection of elements and allows duplicates.
The term ‘List is ordered’ means that the order is retained in which we add elements, and will get the same sequence while retrieving elements.
List interface has three concrete subclasses:
Remember the following three important methods of List :
The ArrayList extends the AbstractList and implements the List interface. It is usually slower than the other arrays, but is useful where you need to manipulate a lot in programs.
Uses Dynamic array for storing the elements
Duplicate elements are allowed
Maintains insertion order
Methods are not synchronised
Random access as it works on index basis
Manipulation is slow because lot of shifting needs to be done. This means that if the ArrayList has 1000 elements and we remove the 50th element, then the 51st element tries to acquire that 50th position and likewise all elements. So, moving every element consumes a lot of time.
The vector class ‘implements a growable array of objects. Similar to an array, it contains components that can be accessed using an integer index’. The vector may expand or contract as per the requirements.
All methods are synchronised
It is slower than an Arraylist
Vector is thread-safe as it has synchronised methods
It has capacity concept. The default capacity is 10
It doubles when it reaches its threshold
Size methods returns the number of elements present
Capacity method returns the capacity which doubles after reaching the default capacity, which is 10
Vector can be iterated by simple for loop, Iterator, ListIterator and Enumeration
Example
package com.javabykiran.collection;
import java.util.ArrayList;
import java.util.Iterator;
/*
* @author Java By Kiran
*/
public class ArrayListTest {
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add("aaa");
al.add("bbb");
al.add("ccc");
// see return type of add below
System.out.println(al.add("ddd"));
al.size();
System.out.println(al.size);
//to check if Arraylist is empty
al.isEmpty();
System.out.println("iteration of Arraylist by for loop");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
System.out.println("iteration of Arraylist by Iterator");
Iterator itr = al.iterator();
while (itr.hasNext()) {
Object o = itr.next(); //this is removed in
//jdk 1.5 and after by autoboxing
String s = (String) o;
System.out.println(s);
}
System.out.println("iteration of Arraylist by List Iterator");
ListIterator ltr = al.listIterator();
while (ltr.hasNext()) {
Object o = ltr.next();
String s = (String) o;
System.out.println(s);
//Object op = ltr.previous();
/*String prevStr = (String) op;
System.out.println(prevStr);*/
}
}
}
Output:
true
4
iteration of Arraylist by for loop
aaa
bbb
ccc
ddd
iteration of Arraylist by Iterator
aaa
bbb
ccc
ddd
iteration of Arraylist by List Iterator
aaa
bbb
ccc
ddd
Example for vector :
package com.javabykiran.Collection; import java.util.Vector;
/*
* @author Java By Kiran
*/
public class VectorTest {
public static void main(String[] args) {
Vector v = new Vector();
System.out.println(v.size());
System.out.println(v.capacity());
//we can change its default behaviour
Vector v1 = new Vector(2);
System.out.println(v1.size());
System.out.println(v1.capacity());
//now try adding elements
v1.add("apple");
v1.add("mango");
v1.add("grapes");
System.out.println(v1.size());
// observe capacity
System.out.println(v1.capacity());
//Iterate by using Enumeration
Enumeration enumeration=v1.elements();
while (enumeration.hasMoreElements()) {
String element =(String)enumeration.nextElement();
System.out.println(element);
}
}
}
Output:
0
10
0
2
3
4
apple
mango
grapes
Example of ArrayList
ArrayList al=new ArrayList (); //with default constructor
ArrayList al1=new ArrayList (al); //constructor with ArrayList
ArrayList al2=new ArrayList (v); //constructor with vector
ArrayList al3=new ArrayList (c); //with java.util.collection
Example of Vector
Vector v=new Vector (); //with default constructor
v.add(); //to add elements
Vector v1=new Vector (al); //with java.util.collection
Vector v2=new Vector(v); // with vector
Iterator | Enumeration |
---|---|
|
|
|
|
|
|
ListIterator is the sub interface of Iterator and therefore has more features in ListIterator than Iterator.
ListIterator can access elements in forward and reverse directions.
Adding elements by using add method.
Replacement of existing elements with new element by using the set method.
Access index of element.
Iterator | ListIterator |
---|---|
|
|
|
|
|
|
|
|
|
|
Array | ArrayList |
---|---|
|
|
|
|
|
|
|
|
Note: Both Array and ArrayList store the elements internally using indexing representation and these elements can be accessed randomly
a [1]
al [0] is not allowed but al.get(0) is allowed
Comparison between ArrayList, Vector and LinkedList:
Topic | ArrayList | Vector | LinkedList |
---|---|---|---|
Legacy or collection Framework | Collection framework class added in java 2 | Legacy class but revised in java 2 | Collection framework class added in java 2 |
Synchronised | Not Synchronised | Synchronised | Not Synchronised |
Storage Representation | Index Representation | Index Representation | Node Representation |
Accessing Elements | Iterator. List Iterator | Enumeration. Iterator List Iterator | Iterator. List Iterator |
Access Type | Random Access | Random Access | ---- |
A set is used to store the collection of elements without duplicates.
It is an unordered collection which means that order is not maintained while storing elements and while retrieving them, we may not get the same order that we had put them in.
A set cannot be iterated by using ListIterator but by Iterator.
Example: Consider the following program of HashSet
package com.javabykiran.Collection;
import java.util.HashSet;
import java.util.Iterator;
/*
* @author Java By Kiran
*/
public class HashSetTest {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add("aaaa");
hs.add("bbbb");
// aaaa will not be allowed as the set doesn't allow duplicates
hs.add("aaaa");
hs.add("cccc");
// see size
System.out.println(hs.size());
// we can print values for testing
System.out.println(hs);
// By using iterator
Iterator itr = hs.iterator();
while (itr.hasNext())
System.out.println(itr.next());
}
}
Output:
3
[bbbb, aaaa, cccc]
bbbb
aaaa
cccc
Comparison between HashSet, LinkedHashSet and TreeSet:
Topic | HashSet | LinkedHashSet | TreeSet |
---|---|---|---|
Duplicate | Not Allowed | Not Allowed | Not Allowed |
Ordering | Unordered | Maintains insertion order | Maintains sorting order |
Null | Allow | Allow | Do not allow |
Accessing Elements | Iterator | Iterator | Iterator |
Thread Safety | No | No | No |
The Queue is an interface of a subtype of the Collection interface
It represents an ordered list of objects just like a List, but its intended use is slightly different.
A queue is designed to have elements inserted at the end of the queue, and elements removed from the beginning of the queue. Just like a queue in a supermarket or any shop.
Dequeue is a sub-interface of Queue interface
A double-ended-queue is a linear collection of elements that supports the insertion and removal of elements at both end points
It defines methods to access the elements at both ends of the Deque instance
Type of Operation | First Element (Beginning of the Deque instance) | Last Element (End of the Deque instance) |
---|---|---|
Insert | addFirst(e) offerFirst(e) |
addLast(e) offerLast(e) |
Remove | removeFirst(e) pollFirst(e) |
removeLast(e) pollLast(e) |
Examine | getFirst(e) peekFirst(e) |
getLast(e) peekLast(e) |
A map is used to store the key-value pair
It doesn't allow duplicate keys but duplicate values are allowed
A HashMap is class which implements the Map interface
It stores values based on key
It is unordered, which means that the key must be unique
It may have null key-null value
For adding elements in HashMap we use the put method
Return type of put method is Object
It returns the previous value associated with key or null if there was no mapping for key
Example:
package com.javabykiran.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/*
* @author Java By Kiran
*/
public class HashMapTest {
public static void main(String[] args) {
// Creation of HashMap
HashMap hm = new HashMap();
// Adding elements with key
hm.put("101", "java");
hm.put("102", ".Net");
// Will print null
Object o = hm.put("103", "C++");
System.out.println(o);
// Will print previous value as it is duplicate value
Object o1 = hm.put("103", "C");
System.out.println(o1);
//1. Retrieving elements from HashMap by using iterator
System.out.println("======By using Iterator======");
Set s = hm.keySet(); // set s contains all keys
Iterator itr = s.iterator();
while (itr.hasNext()) {
String key = (String) itr.next();
System.out.println("Key :"+key);
System. out. println(" Value :"+ hm.get(key));
}
//2. Retrieving elements from HashMap by using Map.Entry
System.out.println("====== By using Map.Entry ======");
// Get a set of the entries
Set set = hm.entrySet();
// Get an iterator
Iterator it = set.iterator();
// Display elements
while(it.hasNext()) {
Map.Entry me = (Map.Entry) it.next();
System.out.print(me.getKey()+ ": ");
System.out.println(me.getValue());
}
}
}
Output:
null
C++
======By using Iterator======
Key :101
Value :java
Key :102
Value :.Net
Key :103
Value :C
====== By using Map.Entry ======
101: java
102: .Net
103: C
A LinkedHashMap is a ‘hastable and linked list implementation of the map interface with a predictable iteration order.
It is the same as HashMap except it maintains an insertion order i.e. ordered
Consider the same above programs using LinkedHashMap. Observe the output. Change one line in the above example.
In above program,
//Instead of
HashMap hm=new HashMap ();
//Use below
// Creation of LinkedHashMap
LinkedHashMap hm = new LinkedHashMap()
Output:
null
C++
====== By using Iterator ======
Key :101
Value :java
Key :102
Value :.Net
Key :103
Value :C
====== By using Map.Entry ======
101: java
102: .Net
103: C
The TreeMap is a class which implements NavigableMap interface which is the sub- interface of SortedMap.
It stores values based on key
It is ordered but in an Ascending manner
Keys should be unique
It cannot have null key at run time but can have null values because the interpreter will not understand how to sort null with other values
Consider the program of storing elements using TreeMap
Example:
package com.javabykiran.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
/*
* @author Java By Kiran
*/
public class TreeMapTest {
public static void main(String[] args) {
// Creation of TreeMap
TreeMap tm = new TreeMap();
// adding elements with key
tm.put("103", "java");
tm.put("102", ".Net");
Object o = tm.put("101", "C++");
// below will print null
System.out.println (o);
Object o1 = tm.put("101", "C");
System.out.println (o1);
// retrieving elements from TreeMap
Set s = tm.keySet();
// set s contains all keys
Iterator itr = s.iterator();
while (itr.hasNext()) {
String key = (String) itr.next();
System.out.println("Key :" + key);
System.out.println("Value :" + tm.get(key));
}
// Try putting null value
// will not throw compile time error
// but gives runtime error uncomment below
// tm.put(null, null);
}
}
Output:
null
C++
Key :101
Value :C
Key :102
Value :.Net
Key :103
Value :java
Hashtable is a class which implements Map interface and extends Dictionary class.
It stores values based on key
It is unordered and the key should be unique
It cannot have null keys or null values. It gives runtime error if we try to add any null keys or values but will not show an error at compile time.
It has synchronised methods and slower than hashmap
Consider the program of storing elements using Hashtable
Example:
package com.javabykiran.Collection;
import java.util.Hashtable;
/*
* @author Java By Kiran
*/
public class HashTableTest {
public static void main(String[] args){ Hashtable ht = new Hashtable(); ht.put("ind", "India");
ht.put("bhu", "Bhutan");
ht.put("ind", "India");
//the below will print size of ht by
//ignoring the duplicate key
System.out.println("size of hashTable> "+ht.size()); // 2
//OK - compile time
//NOT OK AT RUNTIME
//ht.put(null, "India");
//OK - compile time
//NOT OK AT RUNTIME
//ht.put(null, null);
//OK - compile time
//NOT OK AT RUNTIME
//ht.put("ind", null);
System.out.println(ht.size()); // 2
}
}
Output:
size of hashTable > 2
Exception in thread "main" java.lang.NullPointerException
at java.util.Hashtable.put(Unknown Source)
at com.javabykiran.Collection.HashTableTest.main(HashTableTest.java:23)
Comparison between HashMap, LinkedHashMap, TreeMap and HashTable:
Topic | HashMap | LinkedHashMap | TreeMap | HashTable |
---|---|---|---|---|
Duplicate Key | Not Allowed | Not Allowed | Not Allowed | Not Allowed |
Ordering | Unordered | Maintains insertion order | Maintains in Accessing order | Unordered |
Null (Key Value) | Allow | Allow | key Not allowed but value is Iterator | Not Allowed |
Accessing Elements | Iterator | Iterator | Iterator | Iterator |
Thread Safety | No | No | No | Yes |
It can be used to get properties from xml file or to store data in xml file.
All methods of this class are synchronised, So it is a thread-safe class
It is since jdk 1.0
It is the subclass of HashTable
It stores the key-value pair, but both as string
It can be used to get property value based on property key
It can also be used to get properties of system
It provides easy maintenance
Example:
package com.javabykiran.Collection;
import java.io.FileOutputStream;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
/*
* @author Java By Kiran
*/
public class PropertiesTest {
public static void main(String[] args) {
Properties properties = new Properties();
// Same way we can put elements
properties.put("101", "java");
properties.put("102", "C");
properties.put("103", "C++");
properties.put("104", ".Net");
// to retrieve the elements.
Set s = properties.keySet();
Iterator itr = s.iterator();
while (itr.hasNext()) {
System.out.println(properties.get((String)itr.next()));
}
// to store in xml file
try {
FileOutputStream fout = new FileOutputStream("D:\\prop.xml");
properties.storeToXML(four,"key-value pair");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Output:
.Net
C++
C
java
An XML file is created as shown below in the D drive that we have just printed in above Program
Example:
key-value pair .Net C++ C java
All methods of this class are static. Constructor is private
This class has methods to give extra features to Collection Hierarchy. For example: sort, binary Search, reverse, finding min value, max Value and making list read only.
Those collection classes which are not synchronised will be synchronised by using methods - synchronizedList (), synchronizedMap ()
Example:
package com.javabykiran.Collection;
import java.util.ArrayList;
import java.util.Collections;
/*
* @author Java By Kiran
*/
public class CollectionsTest {
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add("Java");
al.add("By");
al.add("Kiran");
System.out.println("before sorting " + al);
Collections.sort(al);
System.out.println("after sorting" + al);
//To make arraylist object synchronised
Collections.synchronizedList(al);
}
}
Output:
before sorting [Java, By, Kiran]
after sorting [By, Java, Kiran]
Note:
To sort custom objects. For example: One student having age and location We add students in Arraylist and we want to sort these students on the basis of their ages If we use only Collections, it will sort by addresses of the students’ object, which we don't want.
This is not possible with the ordinary sort method. For that we need to use Comparable or Comparator interface, where we need to specify our sorting criteria. Then we can pass that criteria into the sort method.
Comparable interface is primarily used to sort out lists or arrays of custom objects. It contains only one method.
The class whose object has to be compared has to implement Comparable interface and has to override compareTo () method in the following format.
public int compareTo(Object 0bj).
Comparable provides only one way of comparison.
You can sort the elements on based on single data member only. For instance it may be rollno, name, age or anything else.
Example:
Consider the following program of sorting students on the basis of age:
package com.javabykiran.Collection;
/*
* @author Java By Kiran
*/
class Student implements Comparable{
String name;
int age;
public int compareTo(Object obj){
Student s = (Student)obj;
if(age==s.age)
return 0;
else if(age>s.age)
return -1;
return age;
}
}
package com.javabykiran.Collection;
import java.util.*;
/*
* @author Java By Kiran
*/
public class CollectionLab9 {
public static void main(String args[]){
ArrayList al = new ArrayList ();
Student s1 = new Student ();
s1.name = "ABC";
s1.age = 24;
Student s2 = new Student ();
s2.name = "XYZ";
s2.age = 21;
Student s3 = new Student ();
s3.name = "PQR";
s3.age = 19;
al.add(s1);
al.add(s2);
al.add(s3);
Collections.sort(al);
Iterator itr=al.iterator();
while(itr.hasNext()){
Student st= (Student) itr.next ();
System.out.println(st.name+"--"+st.age);
}
}
}
Output:
ABC--24
XYZ--21
PQR--19
Comparator interface is used when you have to order user-defined class objects and contains two methods.
We need to write separate class by implementing Comparator interface by overriding the following method:
public int compare(Object o1,Object o2)
You can write multiple comparators to compare objects in different ways
To use compare() method of Comparator interface for sorting, use following method:
Collections.sort(al , new NameComparator());
package com.javabykiran.Collection;
/*
* @author Java By Kiran
*/
class Student {
String name;
int age;
}
package com.javabykiran.Collection;
/*
* @author Java By Kiran
*/
import java.util.*;
public class AgeComparator implements Comparator{
public int compare(Object o1, Object o2) {
Student s1=(Student)o1;
Student s2=(Student)o2;
if(s1.age==s2.age)
return 0;
else if(s1.age>s2.age)
return 1;
else return -1;
}
}
package com.javabykiran.Collection;
/*
* @author Java By Kiran
*/ import java.util.Comparator;
public class NameComparator implements Comparator {
public int compare(Object o1, Object o2) {
Student s1=(Student)o1;
Student s2=(Student)o2;
return s1.name.compareTo(s2.name);
}
}
package com.javabykiran.Collection;
/*
* @author Java By Kiran
*/
import java.util.*;
public class CollectionLab10 {
public static void main(String args[]){
ArrayList al = new ArrayList();
Student s1 = new Student();
s1.name = "ABC";
s1.age = 24;
Student s2 = new Student();
s2.name = "XYZ";
s2.age = 21;
Student s3 = new Student();
s3.name = "PQR";
s3.age = 19;
al.add(s1);
al.add(s2);
al.add(s3);
System.out.println("Sorting by Name...");
Collections.sort(al,new NameComparator());
Iterator itr=al.iterator();
while(itr.hasNext()){
Student st=(Student)itr.next();
System.out.println(st.name+" "+st.age);
}
System.out.println("sorting by age...");
Collections.sort (al,new AgeComparator());
Iterator itr2=al.iterator();
while (itr2.hasNext()){
Student st= (Student)itr2.next();
System.out.print(st.name);
System.out.println(" "+st.age);
}
}
}
Output:
Sorting by Name...
ABC 24
PQR 19
XYZ 21
Sorting by age...
PQR 19
XYZ 21
ABC 24
The following table gives the properties of derived classes: