Collection Framework Unit 4
Collection Framework Unit 4
Collection Framework Unit 4
Collection Framework
Purpose: To represent many values by using single object.
Problem: To represent 10k values we declare 10k variables. By doing this the
readability of the program is going to be down and this is worst kind of
programming. To overcome this, we can go for arrays and collections.
Arrays: Student[] s = new Student[10000]; We can represent huge no of
homogeneous type of elements by using single object(variable) with arrays.
Collection Framework: Collection framework defines several interfaces and
classes which can be used to represent a group of individual objects as a single
entity (i.e. collection).
Collection(I): Collection is a group of individual objects as a single entity.
Collection is an interface which is used to represent a group of individual
objects as a single entity.
Collections(C): Collections is a utility class presents in java.util package to
define several utility methods like sorting, searching etc. in collection objects.
Ex: To sort an ArrayList Collections.sort(al); al -> ArrayList Object
Arrays vs Collections:
Arrays Collections
1. Array are fixed in size. 1. Collections are growable in nature.
2. W.r.t memory arrays are not 2. W.r.t memory collections are recommended.
recommended.
3. W.r.t performance arrays are 3. W.r.t performance collections are not
recommended. recommended.
4. Arrays can hold only homogeneous 4. Collections can hold both homogeneous and
elements. heterogeneous elements.
5. Arrays are not implemented based 5. Every collection class is implemented based
on any DS. So, readymade method on some standard DS. So, readymade method
support is not available. support is available.
6. Arrays can hold primitive types and 6. Collections can hold only reference
reference types(objects). types(objects).
7. There are no predefined classes in 7. There are so many predefined classes are
Java API which represents arrays. available in Java API (java.util package) which
represents collections.
8. We can’t use the cursors to process 8. We can use cursors to process the collection
the array elements. elements.
Note: Usually we can use collections to hold and transfer Objects from one
place to another place, to provide support for this requirement every collection
already implements Serializable and Cloneable Interfaces.
Serializable and Cloneable are marker interfaces in Java. A marker interface is
an interface with no methods or constants inside it. It's used to signal to the
JVM or other tools that the classes implementing these interfaces have certain
properties or should be treated in a specific way.
The Serializable interface is used to enable serialization, which is the process of
converting an object into a byte stream for storage, transmission, or later
reconstruction.
The Cloneable interface is used to indicate that a class allows for cloning, which
is the process of creating a copy of an object.
RandomAccess: RandomAcess interface presents in java.util package and it
doesn’t contain any methods, so it is a marker interface, where required ability
will be provided by JVM automatically.
LinkedList: LinkedList is implemented as a doubly-linked list, where each node
contains a reference to both the previous and next node in the sequence. This
allows for efficient insertions and deletions at both ends and in the middle of
the list.
Properties:
• The underlying DS is Doubly LinkedList.
• Duplicates are allowed and Insertion order is preserved.
• Heterogeneous elements are allowed and null insertion is possible.
• If our frequent operation is insertion or deletion in the middle, then
LinkedList is the best choice. Because the internal structure of the
LinkedList. LinkedList is the worst choice if our frequent operation is
retrieval operation.
• LinkedList implements Serializable and Clonable interfaces but not
RandomAccess interface.
Usually we can use LinkedList to implement stacks and queues to provide
support for this requirement LinkedList class defines following specific
methods.
addFirst(), addLast(), getFirst(), getLast(), removeFirst(), removeLast().
LinkedList ll = new LinkedList();
LinkedList l = new LinkedList(Collection c);
Example
public class TestLinkedList {
public static void main(String[] args) {
LinkedList ll = new LinkedList();
ll.add("java");
ll.add(30);
ll.add(null);
ll.add("java");
System.out.println(ll);
ll.set(0, "python");
System.out.println(ll);
ll.removeLast();
ll.addFirst("c++");
System.out.println(ll);
}}
Output
[java, 30, null, java]
[python, 30, null, java]
[c++, python, 30, null]
Vector: Vector is a part of the Java Collection Framework and is included in the
java.util package. It is an implementation of the List interface, providing a
dynamic array that can grow as needed.
Properties:
• The underlying DS is resizable array or growable array.
• Duplicates are allowed and Insertion order is preserved.
• Heterogeneous elements are allowed and null insertion is possible.
• Every method present in the vector is synchronized and hence vector
object is thread safe.
Method of vector
• addElement(Object o) method from Vector(C)
• removeElement(Object o) method from Vector(C)
• removeElementAt(int index) method from Vector(C)
• removeAllElements() method from Vector(C)
• Object firstElement() method from Vector(C) //For Acccessing
Elements.
• Object lastElement() method from Vector(C)
• int size() – how many elements are present in the vector
• int capacity() – how many objects the vector can hold
• Enumeration elements() – to get the objects one by one from the
collection
Vector v = new Vector();
Creates an empty vector object with default initial capacity 10. Once Vector
reaches its max capacity then a new vector will be crated with (double)
capacity = current capacity*2.
Vector v = new Vector(int initial_capacity);
Vector v = new Vector(int initial_capacity, int incremental_capacity);
Vector v = new Vector(Collection c);
Example
import java.util.Vector;
public class TestVector {
public static void main(String[] args) {
Vector v = new Vector();
for(int i=1; i<=10;i++) {
v.addElement(i);
}
System.out.println(v.capacity());
v.addElement("A");
System.out.println(v.capacity());
System.out.println(v);
}
}
Output
10
20
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, A]
Stack Class
Stack is a class presents in java.util package which extends from Vector class.
So, it is the child class of Vector and it is a specially designed for last-in-first-out
(LIFO) order.
Stack s = new Stack();
Method of Stack
push(Object o) – To insert an object into the Stack
pop(Object o) – To remove an object and return the top of the Stack
peek() – To return top of the Stack without removal
empty() – Returns true if the Stack is empty
int search(Object o) – Returns offset if the element is available otherwise
returns -1
Example
import java.util.Stack;
public class TestStack {
public static void main(String[] args) {
Stack s = new Stack();
s.push("A");
s.push("B");
s.push("C");
System.out.println(s);
System.out.println(s.search("A"));
System.out.println(s.search("Z"));
System.out.println(s);
s.pop();
System.out.println(s);
s.pop();
System.out.println(s);
}}
Output
[A, B, C]
3
-1
[A, B, C]
[A, B]
[A]
Cursors: If you want to get object one by one from the collection then we
should go for cursor.
There are 3 types of cursors available in Java. 1. Enumeration 2. Iterator 3.
ListIterator
1. Enumeration(I): We can use Enumeration to get objects one by one from
legacy collection object. We can create Enumeration object by using
elements() method of Vector class.
Ex: Enumeration e = v.elements();
Methods:(i) public boolean hasMoreElements(); (ii) public object
nextElement();
Limitations of Enumeration:
(i)We can apply Enumeration concept only for legacy classes and it is not
a universal cursor.
(ii) By using Enumeration, we can get only read access and we can’t
perform remove operation To overcome above limitations, we should go
for Iterator.
Example:
import java.util.Enumeration;
import java.util.Vector;
public class TestEnum {
public static void main(String[] args) {
Vector v = new Vector();
for(int i =0;i<=5;i++) {
v.addElement(i);
}
System.out.println(v);
Enumeration e = v.elements();
while(e.hasMoreElements())
{
Integer I = (Integer) e.nextElement();
System.out.println(I);
} }}
2. Iterator(I): We can apply Iterator concept for any collection object and
hence it is universal cursor. By using Iterator we can perform both read
and remove operations. We can create Iterator object by using iterator()
method of collection interface.
Ex: Iterator itr = c.iterator();
Methods: (i) public boolean hasNext(); (ii) public Object next(); (iii) public
void remove();
Limitations of Iterator:
(i) By using Enumeration and Iterator we can always move only forward
direction and we can’t move backward direction these are single
direction cursors but not bidirectional cursors.
(ii) By using Iterator, we can perform only read and remove operations
and we can’t perform replacement and addition of new objects
To overcome above limitations, we should go for ListIterator
Example:
import java.util.ArrayList;
import java.util.Iterator;
public class TestItr {
Both keys and values are objects only. Duplicate keys are not allowed but duplicate
values are allowed.
Methods
(a) Object put(Object key, Object value) – to add one key value pair to the Map. If
the key is already present, then old value will be replaced with new value and
returns old value.
Ex: m.put(101, “A”); // Add this entry to the Map and returns null
m.put(101, “B”);// Replace ‘A’ with ‘B’, has same key and returns ‘A’
(b) void putAll(Map p) - Add the specified Map to current Map /Ex: m1.add(m2)
(c) Object get(Object key) – Returns the value associated with specified key.
(d) Object remove(Object key) – Removes the entry associated with specified key.
(e) boolean containsKey(Object key) - Search the specified key in the Map.
(f) boolean containsValue(Object value) - Search the specified value in the Map.
(g) boolean isEmpty()
(h) int size()
(i) void clear() – All key value pairs will be removed from the Map.
Collection Views of Map Methods:
(j) Set keySet() - returns the Set containing all the keys
(k) Collection values() – returns the Set containing all the values
(l) Set entrySet() - return the Set view containing all the keys and values
Entry(I): Entry is the sub interface of Map. We will be accessed it by Map.Entry name.
A Map is a group of key value pairs and each key value pair is called an entry. Hence,
Map is considered as a collection of entry objects. Without existing Map object, there
is no chance of existing entry object.
Methods:
(a) Object getKey() – used to obtain key
(b) Object getValue() - used to obtain value
(c) Object setValue(Object o) - used to replace the old value with new value
HashMap(C): HashMap is a class presents in java.util package which implements from
Map, Cloneable, Serializable interfaces.
Properties:
• The underlying DS is Hash table.
• Insertion order is not preserved and it is based on hash code of keys.
• Duplicate keys are not allowed, but values can be duplicated.
• Heterogeneous objects are allowed for both key and value.
• Null is allowed for key (only once). Null is allowed for value (any no of tomes).
• HashMap is the best choice if our frequent operation is search operation.
(a) HashMap m = new HashMap();
Creates an empty HashMap with default initial capacity 16 and default fill ratio 0.75.
(b) HashMap m = new HashMap(int initial_capacity);
(c) HashMap m = new HashMap(int initial_capacity, float fill_ratio);
(d) HashMap m1 = new HashMap(Map m2);
Creates HashMap object ‘m1’ by using the elements of the given Map object m2.
Example:
import java.util.HashMap;
import java.util.Map;
public class HashMapExample {
public static void main(String[] args) {
// Creating a HashMap using the Map interface
HashMap<String, Integer> map = new HashMap<>();
// Adding key-value pairs to the HashMap
map.put("Apple", 10);
map.put("Banana", 20);
map.put("Orange", 30);
// Retrieving a value associated with a key
int appleCount = map.get("Apple");
System.out.println("Count of Apple: " + appleCount);
// Iterating over the key-value pairs
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}}}
Output:
Count of Apple: 10
Banana is available.
Key: Apple, Value: 10
Key: Orange, Value: 30
Key: Banana, Value: 20
LinkedHashMap(C): LinkedHashMap is a class presents in java.util package which
extends (inherits) from HashMap class and implements from Map, Cloneable and
Serializable interfaces.
Example:
import java.util.LinkedHashMap;
import java.util.Map;
public class LinkedHashMapExample {
public static void main(String[] args) {
// Creating a LinkedHashMap using the Map interface
Map<String, Integer> linkedHashMap = new LinkedHashMap<>();
// Adding key-value pairs to the LinkedHashMap
linkedHashMap.put("Apple", 10);
linkedHashMap.put("Banana", 20);
linkedHashMap.put("Orange", 30);
linkedHashMap.put("Grapes", 40);
// Retrieving a value associated with a key
int appleCount = linkedHashMap.get("Apple");
System.out.println("Count of Apple: " + appleCount);
// Iterating over the key-value pairs
System.out.println("Entries in the LinkedHashMap:");
for (Map.Entry<String, Integer> entry : linkedHashMap.entrySet()) {
System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}
// Removing a key-value pair
linkedHashMap.remove("Orange");
// Checking the size of the LinkedHashMap
System.out.println("Size of LinkedHashMap after removing Orange: " +
linkedHashMap.size());
// Iterating over the key-value pairs again to show the current state
System.out.println("Entries in the LinkedHashMap after removal:");
for (Map.Entry<String, Integer> entry : linkedHashMap.entrySet()) {
System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
} }}
Output:
Count of Apple: 10
Entries in the LinkedHashMap:
Key: Apple, Value: 10
Key: Banana, Value: 20
Key: Orange, Value: 30
Key: Grapes, Value: 40
Size of LinkedHashMap after removing Orange: 3
Entries in the LinkedHashMap after removal:
Key: Apple, Value: 10
Key: Banana, Value: 20
Key: Grapes, Value: 40
== vs equals():
In general, == operator meant for reference comparison (address comparison)
whereas equals() method meant for content comparison.
Ex: Integer i1 = new Integer(10); i1
Integer i2 = new Integer(10); i2
SOP(i1 == i2); // false
SOP(i1.equals(i2)); // true
SortedMap(I): SortedMap is the child interface of Map interface. If we want to
represent a group of key value pairs according to some sorting order of keys, then we
should go for SortedMap.
SortedMap interface defines the following specific methods.
(a) Object firstKey() - returns first element of the SortedMap
(b) Object lastKey() - returns last element of the SortedMap
(c) SortedSet headMap(Object key) – returns SortedMap whose elements are < key
(d) SortedSet tailMap(Object key) - returns SortedMap whose elements are >= key
(e) SortedSet subMap(Object key1, Object key2) - returns SortedMap whose
elements are >= key1 and < key2
(f) Comparator comparator() – return Comparator object that describes underlying
sorting technique like ascending, descending etc. If we are using default natural
sorting order, then we will get null.
NavigableMap(I): NavigableMap is the child interface of SortedMap. It defines
several methods for navigation purposes. NavigableMap defines the following
methods.
(a) floorKey(e) - Returns the greatest key less than or equal to the given key, or null if
none.
(b) lowerKey(e) - Returns the greatest key strictly less than the given key.
(c) ceilingKey(e) - Returns the least key greater than or equal to the given key, or null
if none.
(d) higherKey(e) - Returns the least key strictly greater than the given key, or null if
none.
(e) pollFirstEntry() – remove and return first element
(f) pollLastEntry() – remove and return last element
(g) descendingMap() – returns NavigableMap in reverse order
TreeMap(C): TreeMap is a class presents in java.util package which implements from
NavigableMap, Cloneable, Serializable interfaces.
Properties:
The underlying DS is Red-Black tree.
Insertion order is not preserved and it is based on some sorting order of keys.
Duplicate keys are not allowed, but values can be duplicated.
If we are depending on default natural sorting order, then keys should be
homogeneous and comparable otherwise we will get RE as ClassCastException.
If we are defining our own sorting by Comparator, then keys need not be
homogeneous and comparable. We can take heterogeneous non-comparable objects
also.
Whether we are depending on default natural sorting or customized sorting order
there are no restrictions for values. We can take heterogeneous non-comparable
objects also.
Null Acceptance:
(i) For non-empty TreeMap if we are trying to insert an entry will ‘null’ key then we
will get RE as NullPointerException.
(ii) For empty TreeMap as the first entry with ‘null’ key is allowed but after inserting
that entry if we are trying to insert any other entry then we will get RE as
NullPointerException.
Note: The above ‘null’ acceptance rule applicable until 1.6v only. From 1.7v on
wards ‘null’ is not allowed for key. But for values we can use ‘null’ any no of times
there is no restriction whether it is 1.6v or 1.7v.
Example:
import java.util.Map;
import java.util.TreeMap;
public class TreeMapExample {
public static void main(String[] args) {
// Creating a TreeMap
TreeMap<Integer, String> treeMap = new TreeMap<>();
// Adding entries to the TreeMap
treeMap.put(13, "Three");
treeMap.put(10, "One");
treeMap.put(2, "Two");
treeMap.put(15, "Five");
treeMap.put(4, "Four");
// Displaying the TreeMap
System.out.println("TreeMap: " + treeMap);
// Iterating through the TreeMap
for (Map.Entry<Integer, String> entry : treeMap.entrySet()) {
System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue()); }
System.out.println(treeMap. firstKey());
System.out.println(treeMap. headMap(3));
System.out.println(treeMap.tailMap(4));
System.out.println(treeMap.subMap(3,5));
System.out.println("floor "+treeMap.floorKey(4));
System.out.println("lower "+treeMap.lowerKey(5));
System.out.println("ceiling "+treeMap.ceilingKey(5));
System.out.println("pollFirstEntry "+treeMap.pollFirstEntry());
System.out.println("TreeMap: " + treeMap);
}}
Hashtable(C): Hashtable is a class presents in java.util package which
extends(inherits) from Dictionary class and implements from Map, Cloneable,
Serializable interfaces.
) Properties:
• The underlying DS is Hash table.
• Insertion order is not preserved and it is based on hash code of keys.
• Duplicate keys are not allowed, but values can be duplicated.
• Heterogeneous objects are allowed for both keys and values.
• ‘null’ is not allowed for both key and values otherwise we will get RE as
NullPointerException.
• Every method present in Hash table is synchronized and hence Hashtable
object is thread safe.