Collection Framework - WP
Collection Framework - WP
It provides an organized ready-made architecture for interfaces and classes which is used for storing
and manipulating a group of objects. A collection is a group of objects or it is a single entity that
represents multiple objects.
Legacy classes:
Collection is a predefined interface which came from java 1.2 version. Before Collection interface, in
order to work with single object, we had Vector class and for working with group of objects we had
Hashtable class which is the sub class for Dictionary class (abstract class). These classes are known as
Legacy classes.
All of these classes had no common interface and working independently Therefore, it was very
difficult for developer to work independently as well as to remember all the different methods, syntax,
and constructor present in every collection class so, from java 1.2 version they decided to re-structure
everything inside a single umbrella and introduced two interfaces i.e., Collection and Map to work
with individual and group of objects respectively.
Collection Hierarchy:
2
c) public boolean addAll(Collection<? extends E> c): Adds all elements of the specified
collection to the end of the list.
d) public boolean addAll(int index, Collection<? extends E> c): Inserts all elements of the
specified collection at the specified position in the list.
e) public void clear(): Removes all elements from the list.
f) public boolean contains(Object o):Returns true if the list contains the specified element.
g) public Object get(int index): Returns the element at the specified position in the list.
h) public int indexOf(Object o): Returns the index of the first occurrence of the specified
element in the list.
i) public boolean isEmpty(): Returns true if the list contains no elements.
j) public Iterator iterator(): Returns an iterator over the elements in the list.
k) public boolean remove(Object o): Removes the first occurrence of the specified element
from the list.
l) public E remove(int index): Removes the element at the specified position in the list.
m) public boolean removeAll(Collection<?> c): Removes all elements in the specified collection
from the list.
n) public boolean retainAll(Collection<?> c): Retains only the elements in the list that are
contained in the specified collection.
o) public int size(): Returns the number of elements in the list.
p) public List subList(int fromIndex, int toIndex): Returns a view of the portion of the list
between the specified fromIndex (inclusive) and toIndex (exclusive).
q) public Object toArray(): Returns an array containing all of the elements in the list.
r) public T[] toArray(T[] a): Returns an array containing all of the elements in the list; the
runtime type of the returned array is that of the specified array.
How many ways we can fetch Collection Object from Collections Framework:
There are 7 ways to fetch these Collection object from Collections Framework
Note: Among all these 7, Enumeration, Iterator and ListIterator these are cursors
Enumeration interface:
We can use Enumeration interface to fetch or retrieve the Objects one by one from the Collection
because it is a cursor.
We can create Enumeration object by using elements() method of the respective Collection class.
a) public boolean hasMoreElements() :- It will return true if the Collection is having more
elements.
b) public Object nextElement() :- It will return collection object so return type is Object.
Iterator interface:
It is used to fetch/retrieve the elements from the Collection in forward direction only.
public Iterator iterator();
Example:
ListIterator interface:
It is a predefined interface available in java.util package and it is the sub interface of Iterator.
It is used to retrieve the Collection object in both the direction i.e. in forward direction as well as in
backward direction.
Example:
ListIterator lit = v.listIterator();
a) public boolean hasNext(): It will verify the element is available in the next position or not, if
available it will return true otherwise it will return false.
b) public Object next(): It will return the next position collection object.
5
c) public boolean hasPrevious(): It will verify the element is available in the previous position or
not, if available it will return true otherwise it will return false.
d) public Object previous (): It will return the previous position collection object.
Note: Apart from these 4 methods we have add(), set() and remove() methods in ListIterartor
interface.
The following program explains how forEach(Consumer cons) method works internally.
package com.ravi.intro;
import java.util.Vector;
import java.util.function.Consumer;
fruits.forEach(cons);
}
}
6
The following program explains how many ways we can fetch Collection Object(All 7 ways).
package com.ravi.intro;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Vector;
while(litr.hasPrevious())
{
System.out.println(litr.previous());
}
System.out.println("FETCHING THE DATA FROM FOREACH METHOD");
fruits.forEach(fruit->System.out.println(fruit));
System.out.println("FETCHING THE DATA USING METHOD REFERENCE");
fruits.forEach(System.out::println);
}
}
ArrayList:
Constructor of ArrayList :
We can copy any Collection interface implemented class data to the current object reference
(Coping one Collection data to another).
8
import java.util.ArrayList;
originalList.add("Java");
originalList.add("Python");
originalList.add("C++");
System.out.println("Size :"+arl.size());
System.out.println("Contents :"+arl); //toString() [Apple,....]
Collections.sort(arl);
}
ArrayListDemo1.java
import java.util.ArrayList;
import java.util.Iterator;
arl.forEach(emp->System.out.println(emp));
}
Operation: fetching the elements in forward and backward direction using ListIterator.
import java.util.*;
public class ArrayListDemo3
{
public static void main(String args[])
{
//Arrays class is having static method asList()
List<String> list= Arrays.asList("Ravi","Rahul","Sweta","Ananya","Bina");
Collections.sort(list);
Collections.reverse(list);
ListIterator<String> itr=list.listIterator();
Operation: resizing the capacity of ArrayList Object, adding element based on specific index, using
forEach and Lambda to Modify elements.
import java.util.ArrayList;
city.add("Hyderabad");
12
city.add("Mumbai");
city.add("Delhi");
city.add("Kolkata");
System.out.println("ArrayList: " + city);
import java.io.Serializable;
this.productId = productId;
}
@Override
public String toString() {
return "Product [productId=" + productId + ", productName=" + productName + "]";
}
}
ArrayListSerializationAndDeSerialization.java
import java.io.*;
import java.util.ArrayList;
class ArrayListSerializationAndDeSerialization {
public static void main(String[] args) {
// Serialization and De-serialization on ArrayList<String>
try {
ArrayList<String> al = new ArrayList<>();
al.add("Nagpur");
al.add("Vijaywada");
al.add("Hyderabad");
al.add("Jamshedpur");
// Serialization
FileOutputStream fos = new FileOutputStream("D:\\new\\City.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(al);
// De-serialization
FileInputStream fis = new FileInputStream("D:\\new\\City.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
// Close streams
fos.close();
oos.close();
fis.close();
ois.close();
14
// Serialization
FileOutputStream fos = new FileOutputStream("D:\\new\\Product.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(productList);
System.out.println("Product Data stored successfully");
// De-serialization
FileInputStream fin = new FileInputStream("D:\\new\\Product.txt");
ObjectInputStream ois = new ObjectInputStream(fin);
Object prod = ois.readObject();
// Close streams
fos.close();
oos.close();
fin.close();
ois.close();
Limitation of ArrayList:
The time complexity of ArrayList to insert and delete an element from the middle would be O(n)
because 'n' number of elements will be re-located so it is not a good choice to perform insertion and
deletion operation in the middle of the List. To avoid this we introduced LinkedList as an alternative.
LinkedList:
Methods of LinkedList:
a) public E getFirst() : Returns the first element in current list.
b) public E getLast() : Returns the last element in current list.
c) public E removeFirst() : Removes and returns the first element from current list.
d) public E removeLast() : Removes and returns the last element from current list.
e) public void addFirst(E e) : Inserts the specified element at the beginning of current list.
f) public void addLast(E e) : Adds the specified element to the end of current list.
g) public boolean contains(Object o) : Returns true if current list contains the specified element.
h) public int size() : Returns the number of elements in current list.
i) public boolean add(E e) : Adds the specified element to the end of current list.
j) public boolean remove(Object o) : Removes the first occurrence of the specified element
from current list, if it is present. If current list does not contain the element, it is unchanged.
k) public boolean addAll(Collection<? extends E> c) : Adds all of the elements in the specified
collection to the end of the current list, in the order that they are returned by the specified
collection's iterator.
l) public boolean addAll(int index, Collection<? extends E> c) : Inserts all of the elements in the
specified collection into the current list, starting at the specified position.
m) public void clear() : Removes all of the elements from the current list. The list will be empty
after this call returns.
n) public E get(int index) : Returns the element at the specified position in the current list.
o) public E set(int index, E element) : Replaces the element at the specified position in the
current list with the specified element.
p) public void add(int index, E element) : Inserts the specified element at the specified position
in the current list. Shifts the element currently at that position (if any) and any subsequent
elements to the right (adds one to their indices).
q) public E remove(int index) : Removes the element at the specified position in the current list.
r) public int indexOf(Object o) : Returns the index of the first occurrence of the specified
element in this list, or -1 if the current list does not contain the element.
s) public E peek() : Retrieves, but does not remove, the head (first element) of the current list.
t) public E element() : Retrieves, but does not remove, the head (first element) of the current
list.
u) public E poll() : Retrieves and removes the head (first element) of the current list.
v) public E remove() : Retrieves and removes the head (first element) of the current list.
[Note:-It stores the elements in non-contiguous memory location. The time complexity for
insertion and deletion is O(1). The time complexity for searching O(n).]
import java.util.LinkedList;
Operation: adding elements, adding element at first, adding element at last, fetching first element,
fetching last element, remove first element, remove last element.
import java.util.LinkedList;
// Displaying the LinkedList after adding elements at first and last positions
System.out.println("After adding elements at first and last positions:");
linkedList.forEach(System.out::println);
System.out.println();
}
else if(x.equals("Hyderabad"))
{
lt.add("Ameerpet");
}
else if(x.equals("Pune"))
{
lt.set("Mumbai");
}
}
city.forEach(System.out::println); //Method Reference
}
}
Operation: Using Iterator retrieve the elements and forEachRemaining()
import java.util.LinkedList;
import java.util.Iterator;
import java.util.List;
class Dog
{
public String name;
Dog(String n)
{
name = n;
}
}
public class LinkedListDemo5
{
public static void main(String[] args)
{
List<Dog> d = new LinkedList<>();
Dog dog = new Dog("Tiger");
d.add(dog);
d.add(new Dog("Tommy"));
d.add(new Dog("Rocky"));
Iterator<Dog> i3 = d.iterator();
i3.forEachRemaining(x -> System.out.println(x.name));
System.out.println("size " + d.size());
System.out.println("Get 1st Position Object " + d.get(1).name);
}
}
Operation:Insertion, deletion, displaying and exit using LinkedList with switch case.
import java.util.LinkedList;
import java.util.Scanner;
while (true)
{
System.out.println("Linked List: " + linkedList);
System.out.println("1. Insert Element");
System.out.println("2. Delete Element");
System.out.println("3. Display Element");
System.out.println("4. Exit");
System.out.print("Enter your choice: ");
Vector:
public class Vector<E> extends AbstractList<E> implements List<E>, Serializable, Clonable,
RandomAccess
Just like ArrayList it also implements List, Serializable, Clonable, RandomAccess interfaces.
Constructors in Vector:
We have 4 types of Constructor in Vector
1) Vector v1 = new Vector();
It will create the vector object with default capacity is 10.
2) Vector v2 = new Vector(int initialCapacity);
Will create the vector object with user specified capacity.
3) Vector v3 = new Vector(int initialCapacity, int incrementalCapacity);
Eg :- Vector v = new Vector(1000,5);
Initially It will create the Vector Object with initial capacity 1000 and then when the
capacity will be full then increment by 5 so the next capacity would be 1005, 1010 and so on.
4) Vector v4 = new Vector(Collection c);
Interconversion between the Collection.
Methods Of Vector:
a) public void copyInto(Object[] anArray): Copies the components of this vector into the
specified array.
b) public void trimToSize(): Trims the capacity of this vector to be the vector's current size.
c) public void ensureCapacity(int minCapacity): Increases the capacity of this vector, if
necessary.
d) public void setSize(int newSize): Sets the size of this vector.
e) public int capacity(): Returns the current capacity of this vector.
f) public int size(): Returns the number of components in this vector.
g) public boolean isEmpty(): Tests if this vector has no components.
h) public E elementAt(int index): Returns the component at the specified index.
i) public E firstElement(): Returns the first component (the item at index 0) of this vector.
j) public E lastElement(): Returns the last component of the vector.
k) public void setElementAt(E obj,int index): Sets the component at the specified index of this
vector to be the specified object. The previous component at that position is discarded.
23
l) public void setElementAt(E obj,int index): Sets the component at the specified index of this
vector to be the specified object. The previous component at that position is discarded.
m) public void insertElementAt(E obj,int index): Inserts the specified object as a component in
this vector at the specified index.
n) public E get(int index): Returns the element at the specified position in this Vector.
o) public E set(int index,E element): Replaces the element at the specified position in this
Vector with the specified element.
p) public boolean add(E e): Appends the specified element to the end of this Vector.
q) public boolean remove(Object o): Removes the first occurrence of the specified element in
this Vector If the Vector does not contain the element, it is unchanged. Etc…
Programs on Vector:
Operation: Check capacity, storing elements, fetching element based on index position, Sorting
elements, finding max and min using Collections class method.
import java.util.Collections;
import java.util.Vector;
import java.util.*;
public class VectorExampleDemo4
{
public static void main(String[] args)
{
//starting time for Vector
long startTime = System.currentTimeMillis();
Operation: Adding elements, retrieving elements by using forEach method and lambda expression.
import java.util.Vector;
public class VectorExampleDemo5 {
public static void main(String[] args) {
Vector<String> names = new Vector<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
names.add("David");
Operation: retrieving all elements by using forEach loop, retrieving elements by using Iterator,
retrieving elements by using ListIterator, retrieving elements by using Enumeration and printing the
index of specific element.
25
import java.util.Vector;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Enumeration;
if (elementIndex != -1) {
System.out.println("Index position of " + searchElement + ": " + elementIndex);
} else {
System.out.println(searchElement + " not found in the Vector.");
}
System.out.println();
Stack:
public E push(Object o) :- This method is used to insert an element onto the top of the stack. In Java
1.8, you can use the push method to add elements.
public synchronized E pop() :- To remove and return the element from the top of the Stack
public synchronized E peek() :- Will fetch the element from top of the Stack without removing
public synchronized int search(Object o) :- It will search a particular element in the Stack and it
returns OffSet position. If the element is not present in the Stack it will return -1.
Programs on Stack:
Operations: adding elements using add method, searching element, retrieving elements by using
java 8.
import java.util.Stack;
if (elementIndex != -1) {
System.out.println(searchElement + " found at position " + elementIndex + " from the top of
the stack.");
} else {
System.out.println(searchElement + " not found in the stack.");
}
System.out.println();
while (!stack.isEmpty()) {
String poppedElement = stack.pop();
System.out.println("Popped Element: " + poppedElement);
}
}
}
Operation: adding elements on the top, removing and printing the removed element, fetching the
top element, checking the stack is empty or not.
import java.util.Stack;
}
System.out.println();
ArrayList Vector
An Array List is not synchronized. Vectors are synchronized, making its thread-safe.
As it is not synchronized, ArrayList is fast. Vector is slow compared to ArrayList, as it is
synchronized.
Multiple threads are allowed in ArrayList. Only single thread is allowed in Vector.
The performance of Array List is high. The performance of Vector is low compared to
ArrayList.
Array List is not a legacy class. Vector is a legacy as class introduced earlier in
Java’s history.
Array List only uses iterators for traversing. Vectors can use iterators and enumerations for
traversing.
Array List increase 50% of its current size in cases Vector grows 100% of its current size if the
the number of elements increases its capacity. number of elements outgrows its capacity.
Set Interface:
public interface Set<E> extends Collection<E>
The Set interface is part of the Java Collections Framework and is a member of the Java Util
package (java.util) since 1.2 .
It extends from Collection Interface and It is a unordered collection.
List implementations are ArrayList, LinkedList, Set implementations are HashSet, LinkedHashSet.
Vector, Stack.
The insertion order is maintained by the List. It doesn’t maintain the insertion order of
elements.
List is often used when we need to frequently It is used when we need to store distinct
access the elements using their indices. elements.
30
The listiterator() is used to iterate the List The iterator() method is used to iterate Set
elements. elements.
Set Implementer classes:
Constructors of HashSet:
It will create the HashSet Object with default capacity is 16. The default load fator or Fill Ratio
is 0.75(75% of HashSet is filled up then new HashSet Object will be created having double
capacity).
2) HashSet hs2 = new HashSet(int initialCapacity);
Interconversion of Collection.
Methods of HashSet:
a) public boolean add(E e): Adds the specified element to this set if it is not already present.
b) public boolean remove(Object o): Removes the specified element from this set if it is
present.
c) public void clear(): Removes all of the elements from this set. The set will be empty after this
call returns.
d) public Object clone(): Returns a shallow copy of this HashSet instance: the elements
themselves are not cloned.
e) public boolean contains(Object o): Returns true if this set contains the specified element.
f) public boolean isEmpty(): Returns true if this set contains no elements.
g) public int size(): Returns the number of elements in this set (its cardinality).
Programs on HashSet:
Operation: The following program describes that HashSet internally uses
Hashtable data structure.
hs.forEach(str->System.out.println(str));
32
}
}
Operations: adding elements, retrieving elements, proving that HashSet does not add any duplicate.
import java.util.HashSet;
Operations: Adding all elements from a given Set, removing all the elements from a given Set,
retrieving all the elements from a given set.
import java.util.HashSet;
// Using addAll to add all elements from the second HashSet to the first HashSet
set1.addAll(set2);
34
// Using removeAll to remove all common elements from the first HashSet
set1.removeAll(set2);
Operation: prove that Collection interface add method returns boolean and check the given element
present or not present.
import java.util.*;
public class HashSetDemo2
{
public static void main(String[] args) {
boolean[] ba = new boolean[6];
Set s = new HashSet();
ba[0] = s.add("a");
ba[1] = s.add(42);
ba[2] = s.add("b");
ba[3] = s.add("a");
ba[4] = s.add("new Object()");
ba[5] = s.add(new Object());
for(int x = 0; x<ba.length; x++)
System.out.println(ba[x]+" ");
Linked HashSet:
linkedHashSet.clear();
System.out.println("After clearing, LinkedHashSet elements: " + linkedHashSet);
}
36
SortedSet Interface:
3) default natural sorting means, if it is number then ascending order and if it is String then
dictionary order or Alphabetical order.
4) We have two interfaces Comparable(available in java.lang package) and Comparator (available in
java.util package) to compare two objects.
Methods of SortedSet:
a) Comparator<? super E> comparator(): Returns the comparator used to order the elements
in this set, or null if this set uses the natural ordering of its elements.
b) SortedSet<E> subSet(E fromElement, E toElement): Returns a view of the portion of this set
whose elements range from fromElement, inclusive, to toElement, exclusive.
c) SortedSet<E> headSet(E toElement): Returns a view of the portion of this set whose
elements are strictly less than toElement.
d) SortedSet<E> tailSet(E fromElement): Returns a view of the portion of this set whose
elements are greater than or equal to fromElement.
e) E first()L Returns the first (lowest) element currently in this set.
f) E last():Returns the last (highest) element currently in this set.
g) default Spliterator<E> spliterator(): Creates a Spliterator over the elements in this sorted set.
Program On Comparable(I):
Employee.java
public class Employee implements Comparable<Employee> {
private Integer employeeId;
private String employeeName;
private Double employeeSalary;
37
ComparableDemo.java
import java.util.ArrayList;
import java.util.Collections;
Collections.sort(empData);
empData.forEach(emp-> System.out.println(emp));
}
}
1) We need to modify the original source code (BLC class), If the source code is not available
then it is not possible to perform sorting operation.
2) We can provide only one sorting logic if we want to provide mutiple sorting logic then it is
not possible.
To avoid the above said problems we introduced Comparator interface available in java.util
package.
Program on Comparator interface(I):
Product.java
public class Product {
38
ProductComparator.java
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
Collections.sort(listOfProduct, prodId);
System.out.println("Sorting based on the Product ID");
Collections.sort(listOfProduct, prodName);
System.out.println("Sorting based on the Product Name");
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
[Note: By default TreeSet add(-) invokes Comparable.compareTo(-) method, when we are adding
objects in TreeSet by using add(-) methods invokes Comparator.compare(O, O) onlywhen we pass
it as argument explicitly by using TreeSet(Comparator) constructor.]
40
Comparable Comparator
Comparable is an interface in Java. Comparator is a functional interface in Java.
Comparable provides compareTo() method to sort Comparator provides compare() method to sort
elements in Java. elements in Java.
Comparable interface is present in java.lang Comparator interface is present in java.util
package. package.
It provides single sorting sequences. Ex: Sort either It provides multiple sorting sequences. Ex. Sort by
by id or name both id and name.
Comparable can be used for natural or default Comparator can be used for custom ordering.
ordering.
Comparable modifies the class that implements it. Comparator doesn't modify any class.
It uses sort(List l). It uses sort(List l, Comparator t).
TreeSet:
Constructors of TreeSet:
Creates an empty TreeSet object, elements will be inserted in a natural sorting order.
Constructs a new, empty tree set, sorted according to the specified comparator.
Constructs a new tree set containing the same elements and using the same ordering as the
specified sorted set.
Methods of TreeSet:
a) public Iterator<E> iterator(): Returns an iterator over the elements in this set in ascending
order.
b) public Iterator<E> descendingIterator()(1.6v): Returns an iterator over the elements in this
set in descending ordfeer.
c) public NavigableSet<E> descendingSet()(1.6v): Returns a reverse order view of the elements
contained in this set.
d) public int size(): Returns the number of elements in this set .
e) public boolean isEmpty(): Returns true if this set contains no elements.
f) public boolean contains(Object o): Returns true if this set contains the specified element.
g) public boolean add(E e Adds the specified element to this set if it is not already present.
h) public boolean remove(Object o): Removes the specified element from this set if it is
present.NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement,
boolean toInclusive): Returns a view of the portion of this set whose elements range
from from Element to to Element.
i) NavigableSet<E> headSet(E toElement, boolean inclusive): Returns a view of the portion of
this set whose elements are less than (or equal to, if inclusive is true) to Element.
j) NavigableSet<E> tailSet(E fromElement, boolean inclusive): Returns a view of the portion of
this set whose elements are greater than (or equal to, if inclusive is true) fromElement.
Etc…………
Programs on TreeSet:
Operations: adding elements, printing in ascending and descending order, fetching elements by
using for Each Remaing().
import java.util.*;
public class TreeSetDemo1 {
public static void main(String[] args) {
SortedSet<String> t1 = new TreeSet<>();
t1.add("Orange");
t1.add("Mango");
t1.add("Pear");
t1.add("Banana");
t1.add("Apple");
System.out.println("In Ascending order");
t1.forEach(i -> System.out.println(i));
}
}
[Note: - descendingIterator() is a predefined method of TreeSet class which will traverse in the
descending order.]
Operations: Working with customized sorting order using Comparator as a parameter.
import java.util.TreeSet;
System.out.println(" ");
System.out.println("Sorting name -> Descending Order");
System.out.println(" ");
System.out.println("Sorting Age -> Ascending Order");
System.out.println(" ");
System.out.println("Sorting Age -> Descending Order");
System.out.println(" ");
System.out.println("Sorting Id -> Ascending Order");
43
System.out.println(" ");
System.out.println("Sorting Id -> Descending Order");
@Override
public String toString(){
return " " + this.id + " " + this.name + " "+ this.age;
}
}
Programs on SortedSet:
Operation: adding elements, fetching first and last element, fetching values less than a range,
fetching elements equal or greater than specific range, fetching values from starting range to ending
range.
import java.util.*;
public class SortedSetMethodDemo
{
public static void main(String[] args) {
TreeSet<Integer> times = new TreeSet<>();
times.add(1205);
times.add(1505);
times.add(1545);
times.add(1600);
times.add(1830);
times.add(2010);
times.add(2100);
Operations: Develop a program to store and fetch the elements by using TreeSet, SortedSet,
NavigableSet.
import java.util.NavigableSet;
import java.util.SortedSet;
import java.util.TreeSet;
// Example of a NavigableSet
NavigableSet<String> t2 = new TreeSet<>();
t2.add("Orange");
t2.add("Mango");
t2.add("Banana");
t2.add("Grapes");
t2.add("Apple");
NavigableSet:
a) E lower(E e): Returns the greatest element in this set strictly less than the given element,
or null if there is no such element.
b) E floor(E e): Returns the greatest element in this set less than or equal to the given element,
or null if there is no such element.
c) E ceiling(E e): Returns the least element in this set greater than or equal to the given
element, or null if there is no such element.
d) E higher(E e): Returns the least element in this set strictly greater than the given element,
or null if there is no such element.
e) E pollFirst(): Retrieves and removes the first (lowest) element, or returns null if this set is
empty.
f) E pollLast(): Retrieves and removes the last (highest) element, or returns null if this set is
empty.
g) NavigableSet<E> descendingSet(): Returns a reverse order view of the elements contained in
this set. The descending set is backed by this set, so changes to the set are reflected in the
descending set, and vice-versa
46
Programs on NavigableSet:
Operations: Use of lower, floor, ceiling, higher methods of NavigableSet.
import java.util.*;
}
}
import java.util.TreeSet;
Explanation:
We create a NavigableSet using TreeSet.
The ceiling method returns the least element greater than or equal to the given element (35 in this
case).
The higher method returns the least element strictly greater than the given element (25 in this case).
The floor method returns the greatest element less than or equal to the given element (35 in this
case).
The lower method returns the greatest element strictly less than the given element (25 in this case).
pollFirst and pollLast methods remove and return the first and last elements, respectively.
Operations: Working with NavigableSet for Range Operation.
import java.util.NavigableSet;
import java.util.TreeSet;
Explanation:
The subSet method creates a subset including the starting element (30) and ending element (70).
We then create a subset of the descending set using subSet, resulting in a descending subset from 70
to 30.
These examples demonstrate the power of NavigableSet in performing range-based operations and
efficiently retrieving elements based on their relationships.
Operations: Descending Iterator with NavigableSet.
import java.util.Iterator;
import java.util.NavigableSet;
import java.util.TreeSet;
The descendingIterator method returns an iterator over the elements in reverse order.
These additional examples showcase the versatility of the NavigableSet interface and its practical
applications in real-world scenarios.
49
Map interface:
Map interface Hierarchy:
Interface Map<K,V>
Type Parameters:
K - the type of keys maintained by this map
V - the type of mapped values
As we know Collection interface is used to hold single or individual object but Map interface
will hold group of objects in the form key and value pair.
Map interface is not the part of Collection.
Before Map interface We had Dictionary(abstract class) class and it is implemented
Hashtable class in JDK 1.0V.
Map interface works with key and value pair introduced from 1.2V.
Here key and value both are objects.
Here key must be unique and value may be duplicate.
Each key and value pair is creating one Entry(Entry is nothing but the combination of key and
value pair).
interface Map{
interface Entry {
}
}
The Map interface provides three collection views, which allow a map's contents to be
viewed as a set of keys, collection of values, or set of key-value mappings.
Map interface has one sub interface that is SortedMap and its has another sub interface that
is NavigableMap.
Methods of Map interface:
1) Object put(Object key, Object value) :- To insert one entry in the Map collection. It will return
the old object value if the key is already available(Duplicate key).
50
6) boolean containsKey(Object key): Returns true if this map contains a mapping for the
specified key.
7) boolean containsValue(Object value): Returns true if this map maps one or more keys to the
specified value.
8) Object get(Object key) :- It will return corresponding value of key, if the key is not present
then it will return null.
9) Object getOrDefault(Object key, Object defaultValue) :- To avoid null value this method has
been introduced, here we can pass some defaultValue to avoid the null value.
10) remove(Object key) :- One complete entry will be removed.
11) putIfAbsent(Object key, Object value) :- It will insert an entry if and only if key is not present ,
if the key is already available then it will not insert the Entry to the Map Collection.
12) int size(): Returns the number of key-value mappings in this map.
13) default boolean remove(Object key, Object value): Removes the entry for the specified key
only if it is currently mapped to the specified value.
14) default boolean replace(K key, V oldValue, V newValue): Replaces the entry for the specified
key only if currently mapped to the specified value.
15) default V replace(K key, V value): Replaces the entry for the specified key only if it is
currently mapped to some value.
This class makes no guarantees as to the order of the map; in particular, it does not
guarantee that the order will remain constant over time.
The default load factor of HashTable is 0.75.
The load factor is a measure of how full the hash table is allowed to get before its capacity is
automatically increased.
We must choose HashMap<K,V> to store only unique entries in single thread application.
Constructors of HashMap:
1) HashMap()
Constructs an empty HashMap with the default initial capacity (16) and the default load factor
(0.75).
2) HashMap(int initialCapacity)
Constructs an empty HashMap with the specified initial capacity and the default load factor
(0.75).
3) HashMap(int initialCapacity, float loadFactor)
Constructs an empty HashMap with the specified initial capacity and load factor.
4) HashMap(Map<? extends K,? extends V> m)
Constructs a new HashMap with the same mappings as the specified Map.
Methods of HashMap: There is no extra method available in HashMap; all the methods are either
overridden from AbstractMap or implemented from the Map interface.So check the Map interface
methods description.
c) While adding the key object in the HashMap, first of all it will invoke the hashCode() method to
retrieve the corresponding key hashcode value.
Example :- hm.put(key,value);
d) If the newly added key and existing key hashCode value both are same (Hash collision), then only
== operator is used for comparing those keys by using reference or memory address, if both keys
references are same then existing key value will be replaced with new key value.
o If the reference of both keys are different then equals(Object obj) method is invoked to
compare those keys by using state(data).
52
o If the equals(Object obj) method returns true (content wise both keys are same), this new
key is duplicate then existing key value will be replaced.
o If equals(Object obj) method returns false, this new key is unique, new entry (key-value) will
be inserted.
Note: equals(Object obj) method is invoked only when two keys are having same hashcode
as well as their references are different.
e) Actually by calling hashcode method we are not comparing the objects, we are just storing the
objects in a group so the currently adding key object will be compared with its HASHCODE GROUP
objects, but not with all the keys which are available in the Map.
f) The main purpose of storing objects into the corresponding group to decrease the number of
comparison so the efficiency of the program will increase.
g) To insert an entry in the HashMap, HashMap internally uses Hashtable data structure.
h) Now, for storing same hashcode object into a single group, hash table data structure internally
uses one more data structure called Bucket.
i) The Hash table data structure internally uses Node class array object.
j) The bucket data structure internally uses LinkedList data structure, It is a single linked list again
implemented by Node class only.
K) A bucket is group of entries of same hash code keys.
L) Performance wise LinkedList is not good to search, so from java 8 onwards LinkedList is
changed to Binary tree to decrease the number of comparison within the same bucket hashcode
if the number of entries are greater than 8.
53
If equals() method invoked on two objects and it returns true then hashcode of both the objects
must be same.
Example:
import java.util.*;
public class HashMapDemo
{
public static void main(String[] args)
{
/*Map<String,String> map = new HashMap<>();
map.put("Ravi","Ampt");
map.put(new String("Ravi"),"Hyd");
System.out.println(map.size());*/
}
}
Programs on HashMap:
Operations: Develop a program to create objects of HashMap by using all 4 constructors and insert
some entries and display it.
import java.util.HashMap;
//Default constructor
int customInitialCapacity = 5;
float loadFactor = 0.75f;
HashMap<String, Integer>hashMap3 = new HashMap<>(customInitialCapacity, loadFactor);
hashMap3.put("Dog", 5);
hashMap3.put("Tiger", 8);
hashMap3.put("Lion", 6);
hashMap3.put("Cat", 4);
System.out.println(map);
System.out.println(map.get(null));
System.out.println(map.get("Virat")); //null becoz key is not available
map.forEach((k, v) -> System.out.println("Key = " + k + ", Value = " + v));
}}
Output is:
{Aswin=5678, null=6390, Rahul=12345, Ravi=1529}
6390
null
Key = Aswin, Value = 5678
Key = null, Value = 6390
Key = Rahul, Value = 12345
Key = Ravi, Value = 1529
[You can see the output that HashMap is not following the insertion order while storing the entries,
hence HashMap is unordered.]
Operations: Inserting key and value pair, searching specific key and value, removing one entry,
retrieving entry based on specific key, fetching data by using forEach method.
import java.util.HashMap;
import java.util.Map;
hashMap.put("Four", 4);
// Removing an entry
String keyToRemove = "Three";
if (hashMap.containsKey(keyToRemove)) {
hashMap.remove(keyToRemove);
System.out.println("Removed key '" + keyToRemove + "'. Updated HashMap: " + hashMap);
} else {
System.out.println("Key '" + keyToRemove + "' not found. No removal performed.");
}
import java.util.*;
public class HashMapDemo1{
public static void main(String args[])
{
HashMap<Integer,String> hm = new HashMap<>();
hm.put(1, "JSE");
hm.put(2, "JEE");
hm.put(3, "JME");
hm.put(4,"JavaFX");
hm.put(5,null);
57
hm.put(6,null);
Operations: Write a program to return a set of keys, return a set of view of mapping and return a
collection view of the values from a map.
import java.util.*;
public class HashMapDemo2
{
public static void main(String args[])
{
Map<Integer,String> map = new HashMap<>();
map.put(1, "C");
map.put(2, "C++");
map.put(3, "Java");
map.put(4, ".net");
newmap1.put(1, "SCJP");
newmap1.put(2, "is");
newmap1.put(3, "best");
//Employee.java
import java.util.*;
class Employee
{
int eid;
String ename;
Employee(int eid, String ename)
{
this.eid = eid;
this.ename = ename;
}
@Override
public boolean equals(Object obj) //obj = e2
{
if(obj instanceof Employee)
{
Employee e2 = (Employee) obj;
if(this.eid == e2.eid && this.ename.equals(e2.ename))
{
return true;
}
else
{
return false;
}
}
else
{
//HashMapDemo8.java
public class HashMapDemo8
{
public static void main(String[] args)
{
Employee e1 = new Employee(101,"Aryan");
Employee e2 = new Employee(102,"Pooja");
Employee e3 = new Employee(101,"Aryan");
Employee e4 = e2;
LinkedHashMap:
Public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>
Constructors of LinkedHashMap:
1. LinkedHashMap()
Constructs an empty insertion-ordered LinkedHashMap instance with the default initial
capacity (16) and load factor (0.75).
2. LinkedHashMap(int initialCapacity)
Constructs an empty insertion-ordered LinkedHashMap instance with the specified initial
capacity and a default load factor (0.75).
Constructs an empty LinkedHashMap instance with the specified initial capacity, load factor
and ordering mode.
a) public boolean containsValue(Object value): Returns true if this map maps one or more keys
to the specified value.
b) public V get(Object key): Returns the value to which the specified key is mapped, or null if
this map contains no mapping for the key.
c) public V getOrDefault(Object key,V defaultValue): Returns the value to which the specified
key is mapped, or defaultValue if this map contains no mapping for the key.
d) public void clear(): Removes all of the mappings from this map. The map will be empty after
this call returns.
e) protected boolean removeEldestEntry(Map.Entry<K,V> eldest): Returns true if this map
should remove its eldest entry.
f) public Set<K> keySet(): Returns a Set view of the keys contained in this map.
g) public Collection<V> values(): Returns a Collection view of the values contained in this map.
h) public Set<Map.Entry<K,V>> entrySet(): Returns a Set view of the mappings contained in this
map.
i) public void forEach(BiConsumer<? super K,? super V> action)
Programs on LinkedHashMap:
Operations: Program to create LinkedHashMap object using all constructors and adding key value
pairs and displaying them.
import java.util.LinkedHashMap;
import java.util.Map;
// Compute the updated price of a specific product using the compute method
private static void computeUpdatedPrice(Map<String, Double> map, String key, BiFunction<String,
Double, Double> function) {
map.compute(key, (product, currentPrice) -> function.apply(product, currentPrice));
}}
Operations: Program to use keyset, values, entrySet on LinkedhashMap.
import java.util.LinkedHashMap;
import java.util.Map;
Hashtable:
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable,
Serializable
It is predefined class available in java.util package under Map interface.
Like Vector, Hashtable is also form the birth of java so called legacy class.
It is the sub class of Dictionary class which is an abstract class.
This class implements a hash table, which maps keys to values. Any non-null object can be
used as a key or as a value.
The objects used as keys must implement the hashCode method and the equals method.
Constructors of Hashtable:
1) Hashtable hs1 = new Hashtable() : It will create the Hashtable Object with default capacity as 11
as well as load factor is 0.75
2) Hashtable hs2 = new Hashtable(int initialCapacity) : will create the Hashtable object with
specified capacity
3) Hashtable hs3 = new Hashtable(int initialCapacity, float loadFactor) : we can specify our own
initialCapacity and loadFactor
4) Hashtable hs = new Hashtable(Map c) : Interconversion of Map Collection.
Programs on Hashtable:
Operations:
65
// Creating a HashMap
Map<String, String> countryCodes = new HashMap<>();
countryCodes.put("USA", "+1");
countryCodes.put("UK", "+44");
countryCodes.put("India", "+91");
// Displaying the content of the Hashtable using forEach with method reference
System.out.println("Display Hashtable using forEach with method reference:");
countryCodeTable.forEach(System.out::println);
}
}
//map.put(5,null);
System.out.println(map);
System.out.println(" ..................... ");
for(Map.Entry m : map.entrySet())
{
System.out.println(m.getKey()+" = "+m.getValue());
}
}
}
[Note: Map is an interface and Entry is also an interface defined inside Map interface to create an
entry]
interface Map {
interface Entry{
//key and value pair
}
}
Operations: Program to add some key if that key is not present.
import java.util.*;
public class HashtableDemo1
{
public static void main(String args[])
67
{
Hashtable<Integer,String> map=new Hashtable<>();
map.put(1,"Priyanka");
map.put(2,"Ruby");
map.put(3,"Vibha");
map.put(4,"Kanchan");
map.putIfAbsent(5,"Bina");
map.putIfAbsent(24,"Pooja");
map.putIfAbsent(26,"Ankita");
map.putIfAbsent(1,"Sneha");
System.out.println("Updated Map: "+map);
}
}
HashMap Hashtable
HashMap is introduced in version 1.2. Hashtable is introduced in version 1.0. So it is
So it is Non-legacy. considered as legacy.
HashMap is not synchronized, therefor not Hashtable is synchronized, therefore be used in
particularly thread-safe. multithreaded implementations.
It can have one null key and many null values. Does not permit null keys or values. Inserting
null can lead to a NullPointerException.
It is faster than the Hashtable and uses less It is much slower than the HashMap
memory.
The iterator is fail-fast. Enumerator is not fail-fast. Due to internal
Throws ConcurrentModificationException if synchronization, concurrent modification risks
modified by another thread during iteration. are minimized during enumeration.
Part of the collection framework from its Initially not part of the collection framework.
introduction. Implements the Map interface. Later integrated after implementing
the Map interface.
Can be used to Does not guarantee any specific order for its
implement LinkedHashMap (maintains entries.
insertion order) and TreeMap (sorted order).
Properties:
Properties class is used to maintain the data in the key-value form. It takes both key and value as a
string. Properties class is a subclass of Hashtable. It provides the methods to store properties in a
properties file and to get the properties from the properties file. System.getProperties() returns the
all system’s properties.
Constructors of Properties:
2. Properties(Properties defaults): Creates an empty property list with the specified defaults.
Methods of Properties:
a) public Object setProperty(String key, String value): Calls the Hashtable method put. Provided
for parallelism with the getProperty method. Enforces use of strings for property keys and
values. The value returned is the result of the Hashtable call to put.
b) public void load(Reader reader) throws IOException: Reads a property list (key and element
pairs) from the input character stream in a simple line-oriented format.
c) public void load(InputStream inStream) throws IOException: Reads a property list (key and
element pairs) from the input byte stream.
d) public void store(Writer writer, String comments)throws IOException: Writes this property
list (key and element pairs) in this Properties table to the output character stream in a
format suitable for using the load(Reader) method.
e) public void store(OutputStream out, String comments) throws IOException: Writes this
property list (key and element pairs) in this Properties table to the output stream in a format
suitable for loading into a Properties table using the load(InputStream) method.
f) public String getProperty(String key): Searches for the property with the specified key in this
property list
g) public String getProperty(String key, String defaultValue): Searches for the property with the
specified key in this property list.
h) public Enumeration<?> propertyNames(): Returns an enumeration of all the keys in this
property list, including distinct keys in the default property list if a key of the same name has
not already been found from the main properties list.
i) public Set<String> stringPropertyNames()
j) public void list(PrintStream out): Prints this property list out to the specified output stream.
This method is useful for debugging.
k) public void list(PrintWriter out): Prints this property list out to the specified output stream.
This method is useful for debugging.
Programs on Properties class:
db.properties
driver = oracle.jdbc.driver.OracleDriver
user = system
password = tiger
import java.util.*;
import java.io.*;
public class PropertiesExample1
{
public static void main(String[] args)throws Exception
{
FileReader reader=new FileReader("db.properties");
System.out.println(p.getProperty("user"));
System.out.println(p.getProperty("password"));
System.out.println(p.getProperty("driver"));
69
}
}
Operations: Program to show the use of Map.entry and getValue.
import java.util.*;
import java.io.*;
public class PropertiesExample2
{
public static void main(String[] args)throws Exception
{
Properties p=System.getProperties();
Set set=p.entrySet();
Iterator itr=set.iterator();
while(itr.hasNext())
{
Map.Entry entry=(Map.Entry)itr.next();
System.out.println(entry.getKey()+" = "+entry.getValue());
}
}
IdentityHashMap:
public class IdentityHashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Clonable,
Serializable.
1. IdentityHashMap(): Constructs a new, empty identity hash map with a default expected
maximum size (21).
2. IdentityHashMap(int expectedMaxSize): Constructs a new, empty map with the specified
expected maximum size.
3. IdentityHashMap(Map<? extends K,? extends V> m):
Constructs a new identity hash map containing the keys-value mappings in the specified
map.
Programs on IdentityHashMap:
70
Operation: Program to check that the IdenticalHashMap stores the object by checking their address
but not by contents.
import java.util.*;
public class IdentityHashMapDemo
{
public static void main(String[] args)
{
HashMap<String,Integer> hm = new HashMap<>();
hm.put("Ravi",23);
hm.put(new String("Ravi"), 24);
ihm.put("Ravi",23);
ihm.put(new String("Ravi"), 27); //compares based on == operator
identityMap.put(key1, "Value1");
identityMap.put(key2, "Value2");
// Size of the map (1, not 2, because key1 and key2 are different objects)
System.out.println("Size of IdentityHashMap: " + identityMap.size());
It is a predefined class in java.util package under Map interface.It was introduced from JDK
1.2v onwards.
While working with HashMap, keys of HashMap are of strong reference type. This means the
entry of map will not be deleted by the garbage collector even though the key is set to be
null and still it is not eligible for Garbage Collector.
On the other hand while working with WeakHashMap, keys of WeakHashMap are of weak
reference type. This means the entry of a map is deleted by the garbage collector if the key
value is set to be null because it is of weak type.
So, HashMap dominates over Garbage Collector where as Garbage Collector dominates over
WeakHashMap.
It contains 4 types of Constructor.
Constructor of WeakHashMap:
1. WeakHashMap()
Constructs a new, empty WeakHashMap with the default initial capacity (16) and load factor
(0.75).
2. WeakHashMap(int initialCapacity)
Constructs a new, empty WeakHashMap with the given initial capacity and the default load
factor (0.75).
Programs on WeakHashMap:
t = null;
Thread.sleep(5000);
System.out.println(map); //{}
}
}
class Test {
@Override
public String toString() {
return "Test Nit";
}
@Override
public void finalize() //called automatically if an object is eligible 4 GC
{
System.out.println("finalize method is called");
}
}
The program sleeps for 5 seconds to allow the garbage collector to act.
After 5 seconds, the WeakHashMap is printed again, and since the key t is now eligible for garbage
collection, the map becomes empty ({}). Additionally, the finalize method of the Test class is called
when the object is garbage collected.
This example demonstrates the behavior of WeakHashMap with weak references and how entries
are automatically removed when keys become unreachable.
SortedMap(I):
1. A void (no arguments) constructor, which creates an empty sorted map sorted according to
the natural ordering of its keys.
2. A constructor with a single argument of type Comparator, which creates an empty sorted
map sorted according to the specified comparator.
3. A constructor with a single argument of type Map, which creates a new map with the same
key-value mappings as its argument, sorted according to the keys' natural ordering.
4. A constructor with a single argument of type SortedMap, which creates a new sorted map
with the same key-value mappings and the same ordering as the input sorted map.
Methods of SortedMap:
a) Comparator<? super K> comparator(): Returns the comparator used to order the keys in this
map, or null if this map uses the natural ordering of its keys.
b) SortedMap<K,V> subMap(K fromKey, K toKey): Returns a view of the portion of this map
whose keys range from fromKey.
c) SortedMap<K,V> headMap(K toKey): Returns a view of the portion of this map whose keys
are strictly less than toKey.
d) SortedMap<K,V> tailMap(K fromKey): Returns a view of the portion of this map whose keys
are greater than or equal to from Key.
e) K firstKey(): Returns the first (lowest) key currently in this map.
f) K lastKey(): Returns the last (highest) key currently in this map.
g) Set<K> keySet(): Returns a Set view of the keys contained in this map.
h) Collection<V> values(): Returns a Collection view of the values contained in this map.
i) Set<Map.Entry<K,V>> entrySet(): Returns a Set view of the mappings contained in this map.
TreeMap:
Constructors of TreeMap:
1. TreeMap()
Constructs a new, empty tree map, using the natural ordering of its keys.
2. TreeMap(Comparator<? super K> comparator)
Constructs a new, empty tree map, ordered according to the given comparator.
3. TreeMap(Map<? extends K,? extends V> m)
Constructs a new tree map containing the same mappings as the given map, ordered
according to the natural ordering of its keys.
4. TreeMap(SortedMap<K,? extends V> m)
74
Constructs a new tree map containing the same mappings and using the same ordering as
the specified sorted map.
Methods of TreeMap: All methods are inherited from AbstractMap,Map(I) ,SortedMap(I) and
NavigableMap.
a) public Map.Entry<K,V> firstEntry(): Returns a key-value mapping associated with the least
key in this map, or null if the map is empty.
b) public Map.Entry<K,V> lastEntry(): Returns a key-value mapping associated with the greatest
key in this map, or null if the map is empty.
c) public Map.Entry<K,V> pollFirstEntry(): Removes and returns a key-value mapping
associated with the least key in this map, or null if the map is empty.
d) public Map.Entry<K,V> pollLastEntry(): Removes and returns a key-value mapping associated
with the greatest key in this map, or null if the map is empty.
e) public Map.Entry<K,V> lowerEntry(K key): Returns a key-value mapping associated with the
greatest key strictly less than the given key, or null if there is no such key.
f) public K lowerKey(K key): Returns the greatest key strictly less than the given key, or null if
there is no such key.
g) public Map.Entry<K,V> floorEntry(K key): Returns a key-value mapping associated with the
greatest key less than or equal to the given key, or null if there is no such key.
h) public K floorKey(K key): Returns the greatest key less than or equal to the given key,
or null if there is no such key.
i) public Map.Entry<K,V> ceilingEntry(K key): Returns a key-value mapping associated with the
least key greater than or equal to the given key, or null if there is no such key.
j) public K ceilingKey(K key): Returns the least key greater than or equal to the given key,
or null if there is no such key.
k) public K higherKey(K key): Returns the least key strictly greater than the given key, or null if
there is no such key.
l) public SortedMap<K,V> subMap(K fromKey, K toKey): Returns a view of the portion of this
map whose keys range from fromKey, inclusive, to toKey, exclusive.
m) public SortedMap<K,V> headMap(K toKey): Returns a view of the portion of this map whose
keys are strictly less than toKey.
n) public SortedMap<K,V> tailMap(K fromKey): Returns a view of the portion of this map
whose keys are greater than or equal to fromKey.
Etc…………
Programs on TreeMap:
Operations: Program to show the use of all Constructors of TreeMap.
import java.util.Comparator;
import java.util.TreeMap;
Operation: Program to store key and value and fetch it by using forEachremaining and forEach.
import java.util.*;
public class TreeMapDemo1
{
public static void main(String args[])
{
TreeMap map = new TreeMap();
map.put("one","1");
map.put("two",null);
map.put("three","3");
map.put("four",4);
displayMap(map);
map.forEach((k, v) -> System.out.println("Key = " + k + ", Value = " + v));
}
static void displayMap(TreeMap map)
{
Collection c = map.entrySet(); //Set<Map.Entry>
76
Iterator i = c.iterator();
i.forEachRemaining(x -> System.out.println(x));
}
}
Operations: Program to see the first key and last key of a TreeMap and show the use ofheadMap(),
submap(), tailMap().
import java.util.TreeMap;
import java.util.Map;
// Retrieving the head of the map (entries less than a specified key)
Map<Integer, String> headMap = treeMap.headMap(3);
System.out.println("Head Map (entries less than key 3): " + headMap);
// Retrieving the tail of the map (entries greater than or equal to a specified key)
Map<Integer, String> tailMap = treeMap.tailMap(3);
System.out.println("Tail Map (entries greater than or equal to key 3): " + tailMap);
System.out.println(tm1);
System.out.println();
System.out.println(tm2);
System.out.println();
System.out.println("\t***********Sorting Age -> Ascending Order***********\t");
System.out.println(tm3);
System.out.println();
System.out.println("\t***********Sorting Age -> Descending
Order***********\t");
TreeMap<Employee,String> tm4 = new TreeMap<>((e1,e2)->-
(e1.age).compareTo(e2.age));
System.out.println(tm4);
}
}
class Employee
{
int id;
String name;
Integer age;
@Override
public String toString()
{
return " " + this.id + " " + this.name + " "+ this.age;
}
}
NavigableMap interface:
Navigation Methods:
a) lowerKey(K key): Returns the greatest key strictly less than the given key, or null if there is no
such key.
b) floorKey(K key): Returns the greatest key less than or equal to the given key, or null if there is
no such key.
c) ceilingKey(K key): Returns the least key greater than or equal to the given key, or null if there
is no such key.
d) higherKey(K key): Returns the least key strictly greater than the given key, or null if there is
no such key.
e) descendingKeySet(): Returns a reverse order NavigableSet view of the keys.
Submap Views:
a) subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive): Returns a view of
the portion of this map whose keys range from fromKey to toKey.
b) headMap(K toKey, boolean inclusive): Returns a view of the portion of this map whose keys
are strictly less than toKey.
c) tailMap(K fromKey, boolean inclusive): Returns a view of the portion of this map whose keys
are greater than or equal to fromKey.
79
Programs on NavigableMap:
import java.util.*;
navigableMap.put(3, "Three");
navigableMap.put(1, "One");
navigableMap.put(5, "Five");
navigableMap.put(2, "Two");
navigableMap.put(4, "Four");
// Navigation methods
System.out.println("lowerKey(3): " + navigableMap.lowerKey(3));
System.out.println("floorKey(3): " + navigableMap.floorKey(3));
System.out.println("ceilingKey(3): " + navigableMap.ceilingKey(3));
System.out.println("higherKey(3): " + navigableMap.higherKey(3));
// Submap views
System.out.println("subMap(2, true, 4, true): " + navigableMap.subMap(2, true, 4, true));
System.out.println("headMap(3, true): " + navigableMap.headMap(3, true));
System.out.println("tailMap(3, true): " + navigableMap.tailMap(3, true));
3) It is an ordered collection.
4) In a queue, insertion is possible from last is called REAR where as deletion is possible from the
starting is called FRONT of the queue.
5) From jdk 1.5 onwards LinkedList class implements Queue interface to handle the basic queue
operations.
6) Besides basic Collection operations, queues provide additional insertion, extraction, and
inspection operations.
a) boolean add(E e)
Inserts the specified element into this queue if it is possible to do so immediately without
violating capacity restrictions, returning true upon success and throwing
an IllegalStateException if no space is currently available.
b) boolean offer(E e)
Inserts the specified element into this queue if it is possible to do so immediately without
violating capacity restrictions.
c) E remove()
Retrieves and removes the head of this queue.
d) E poll()
Retrieves and removes the head of this queue, or returns null if this queue is empty.
e) E element()
Retrieves, but does not remove, the head of this queue.
f) E peek()
Retrieves, but does not remove, the head of this queue, or returns null if this queue is
empty.
Programs on Queue(I):
import java.util.LinkedList;
import java.util.Queue;
1. PriorityQueue(): Creates a PriorityQueue with the default initial capacity (11) that orders its
elements according to their natural ordering.
2. PriorityQueue(Collection<? extends E> c): Creates a PriorityQueue containing the elements
in the specified collection.
3. PriorityQueue(Comparator<? super E> comparator): Creates a PriorityQueue with the default
initial capacity and whose elements are ordered according to the specified comparator.
4. PriorityQueue(int initialCapacity): Creates a PriorityQueue with the specified initial capacity
that orders its elements according to their natural ordering.
5. PriorityQueue(int initialCapacity, Comparator<? super E> comparator): Creates
a PriorityQueue with the specified initial capacity that orders its elements according to the
specified comparator.
6. PriorityQueue(PriorityQueue<? extends E> c): Creates a PriorityQueue containing the
elements in the specified priority queue.
7. PriorityQueue(SortedSet<? extends E> c): Creates a PriorityQueue containing the elements in
the specified sorted set.
Methods of PriorityQueue:
a) public boolean add(E e): Inserts the specified element into this priority queue.
b) public boolean offer(E e):Inserts the specified element into this priority queue.
c) public E peek(): Retrieves, but does not remove, the head of this queue, or returns null if this
queue is empty.
d) public boolean remove(Object o): Removes a single instance of the specified element from
this queue, if it is present.
e) public boolean contains(Object o)Returns true if this queue contains the specified element.
82
f) public Object[] toArray(): Returns an array containing all of the elements in this queue.
g) public <T> T[] toArray(T[] a): Returns an array containing all of the elements in this queue.
i) public void clear(): Removes all of the elements from this priority queue. The queue will be
empty after this call returns.
j) public E poll(): Retrieves and removes the head of this queue, or returns null if this queue is
empty.
k) public final Spliterator<E> spliterator(): Creates a late-binding and fail-fast Spliterator over
the elements in this queue.
Etc…..
Programs on PriorityQueue:
System.out.println(pq.peek()); //Apple
System.out.println(pq.poll()); //Apple
System.out.println(pq.peek()); //Orange
System.out.println(pq); //[Orange]
}
}
[Note:- It stores the elements on basis of Priority in and priority out which internally maintains
priority heap tree order.]
Operation: Program to show the usage of remove, offer in PriorityQueue.
import java.util.PriorityQueue;
public class PriorityQueueDemo1
{
public static void main(String[] argv)
{
PriorityQueue<String> pq = new PriorityQueue<>();
pq.add("9");
pq.add("8");
pq.add("7");
System.out.print(pq.peek() + " ");
pq.offer("6");
pq.offer("5");
83
pq.add("3");
pq.remove("1");
System.out.print(pq.poll() + " ");
if (pq.remove("2"))
System.out.print(pq.poll() + " ");
System.out.println(pq.poll() + " " + pq.peek());
System.out.println(pq);
}
}
Operation: using add method to add some Integer.
import java.util.PriorityQueue;
import java.util.PriorityQueue;
pq.remove("1");
System.out.print(pq.poll() + " "); // 2
if (pq.remove("2"))
System.out.print(pq.poll() + " "); // 3
System.out.println(pq.poll() + " " + pq.peek() + " " + pq.poll()); // 4 6 9
}
}
Generics:
As we know our compiler is known for Strict type checking because java is a statically typed checked
language.
The basic problem with collection is It can hold any kind of Object.
import java.util.*;
class Test1
{
public static void main(String[] args)
{
ArrayList al = new ArrayList(); //raw type
al.add("Ravi");
al.add("Ajay");
al.add("Vijay");
{
String str =(String) t.get(i);
System.out.println(str);
}
t.add(1234);
t.add(1256);
for (int i = 0; i < t.size(); ++i)
{
String obj= (String)t.get(i); //we can't perform type casting here
System.out.println(obj);
}
}
}
To avoid all the above said problem Generics came into picture from JDK 1.5 onwards
-> It deals with type safe Object so there is a gurantee of both the end i.e putting inside and getting
out.
Example:-
ArrayList<String > al = new ArrayList<>();
Now here we have a gurantee that only String can be inserted as well as only String will come out
from the Collection so we can perform String related operation.
Advantages:-
-
import java.util.*;
public class Test3
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<>(); //Generic type
al.add("Ravi");
al.add("Ajay");
al.add("Vijay");
}
}
//Program that describes the return type of any method can be type safe
//[We can apply generics on method return type]
import java.util.*;
public class Test4
{
public static void main(String [] args)
{
Dog d1 = new Dog();
Dog d2 = d1.getDogList().get(1);
System.out.println(d2);
}
}
class Dog
{
public List<Dog> getDogList()
{
List<Dog> d = new ArrayList<>();
d.add(new Dog());
d.add(new Dog());
return d;
}
}
Note:- In the above program the compiler will stop us from returning anything which is not
compaitable List<Dog> and there is a gurantee that only "type safe list of Dog object" will be
returned so we need not to provide type casting as shown below
System.out.println(b);
87
}
}
Note:-
In the above program the compiler will not generate any warning message because even though we
are assigning type safe Integer Object to unsafe or raw type List Object but this List Object is not
inserting anything new in the collection so there is no risk to the caller.
import java.util.*;
public class Test7
{
public static void main(String[] args)
{
List<Integer> myList = new ArrayList<>();
myList.add(4);
88
myList.add(6);
UnknownClass u = new UnknownClass();
int total = u.addValues(myList);
System.out.println(total);
}
}
class UnknownClass
{
public int addValues(List list)
{
list.add(5); //adding object to raw type
Iterator it = list.iterator();
int total = 0;
while (it.hasNext())
{
int i = ((Integer)it.next());
total += i;
}
return total;
}
}
Type Erasure
In the above program the compiler will generate warning message because the unsafe List Object is
inserting the Integer object 5 so the type safe Integer object is getting value 5 from unsafe type so
there is a problem to the caller method.
By writing ArrayList<Integer> actually JVM does not have any idea that our ArrayList was suppose to
hold only Integers.
All the type safe information does not exist at runtime. All our generic code is Strictly for compiler.
There is a process done by java compiler called "Type erasure" in which the java compiler converts
generic version to non-generic type.
List<Integer> myList = new ArrayList<Integer>();
At the compilation time it is fine but at runtime for JVM the code becomes
import java.util.*;
abstract class Animal
{
89
t.checkAnimals(dogs);
90
t.checkAnimals(cats);
t.checkAnimals(birds);
}
}
Note:-From the above program it is clear that polymorphism(Upcasting) concept works with array.
import java.util.*;
abstract class Animal
{
public abstract void checkup();
}
dogs.add(new Dog());
Eg:-
Parent [] arr = new Child[5]; //valid
Object [] arr = new String[5]; //valid
In Array we have an Exception called ArrayStoreException but the same Exception or such type of
exception, is not available with Generics that is the reason in generics compiler does not allow
upcasting concept.
(It is a strict compile time checking)
import java.util.*;
class Parent
{
92
}
class Child extends Parent
{
}
System.out.println("Success");
}
}
<Animal> -: Only <Animal> can assign, but not Dog or sub type
of animal
<? super Dog> -: Dog, Animal, Object can assign (Compiler has surity)
<? extends Animal> -: Below of Animal(Child of Animal) means, sub classes of Animal (But
the compiler does not have surity because you can have many sub classes of Animal in the
future, so chances of wrong collections)
import java.util.*;
class Parent
{
}
class Child extends Parent
{
}
public class Test12
{
public static void main(String [] args)
93
{
List<?> lp = new ArrayList<Parent>();
System.out.println("Wild card ...");
}
}
import java.util.*;
public class Test13
{
public static void main(String[] args)
{
List<? extends Number> list1 = new ArrayList<Integer>();
System.out.println("yes");
}
}
import java.util.*;
public class Test14
{
public static void main(String[] args)
{
try
{
List<Object> x = new ArrayList<>(); //Array of Object[java 9]
x.add(10);
x.add("Ravi");
x.add(true);
x.add(34.89);
System.out.println(x);
}
catch (Exception e)
{
System.out.println(e);
}
}
}
class MyClass<T>
{
T obj;
public MyClass(T obj) //obj = 12 that is Integer Object
{
this.obj=obj;
}
94
T getObj()
{
return obj;
}
}
public class Test15
{
public static void main(String[] args)
{
Integer i=12;
MyClass<Integer> mi = new MyClass<Integer>(i);
System.out.println("Integer object stored :"+mi.getObj());
Float f=12.34f;
MyClass<Float> mf = new MyClass<Float>(f);
System.out.println("Float object stored :"+mf.getObj());
Double d=99.34;
MyClass<Double> md = new MyClass<Double>(d);
System.out.println("Double object stored :"+md.getObj());
}
}
public E getElement()
{
return this.element;
95
}
}
Apple x = (Apple)b.getElement();
System.out.println(x);
}}
1) In the Collection framework most of the Collection classes are not thread-safe because those are
non-synchronized like ArrayList, LinkedList, HashSet, HashMap is non-synchronized in nature, So If
multiple threads will perform any operation on the collection object simultaneously then we will get
some wrong data this is known as Data race or Race condition.
2) Some Collection classes are synchronized like Vector, Hashtable but performance wise these
classes are slow in nature.
Collections class has provided static methods to make our List, Set and Map interface classes as a
synchronized.
3) We can t modify the collection object data while iterating the Collection object. If we try to modify
the collection, it throws ConcurrentModificationException, So non-synchronized collections are not
good choice for Multi-threaded applications.
Programs:
import java.util.*;
public class Collection1
{
96
//Collections.synchronizedList(List list);
import java.util.*;
public class Collection2
{
public static void main(String[] args)
{
ArrayList<String> arl = new ArrayList<>();
arl.add("Apple");
arl.add("Orange");
arl.add("Grapes");
arl.add("Mango");
arl.add("Guava");
arl.add("Mango");
//Collections.synchronizedSet(Set set);
import java.util.*;
public class Collection3
97
{
public static void main(String[] args)
{
Set<String> set = Collections.synchronizedSet(new HashSet<>());
set.add("Apple");
set.add("Orange");
set.add("Grapes");
set.add("Mango");
set.add("Guava");
set.add("Mango");
System.out.println("Set after Synchronization :");
synchronized (set)
{
Spliterator<String> itr = set.spliterator();
itr.forEachRemaining(str -> System.out.println(str));
}
}
}
//Collections.synchronizedMap(Map map);
import java.util.*;
public class Collection4
{
public static void main(String[] args)
{
Map<String, String> map = new HashMap<String, String>();
map.put("1", "Ravi");
map.put("4", "Elina");
map.put("3", "Aryan");
Map<String, String> synmap = Collections.synchronizedMap(map);
System.out.println("Synchronized map is :" + synmap);
}
}
import java.util.*;
class ConcurrentModification extends Thread
{
ArrayList<String> al = null;
public ConcurrentModification(ArrayList<String> al) //al = arl
{
this.al = al;
}
@Override
public void run()
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
98
{
}
al.add("KIWI");
}
}
public class Collection5
{
public static void main(String[] args) throws InterruptedException
{
ArrayList<String> arl = new ArrayList<>();
arl.add("Apple");
arl.add("Orange");
arl.add("Grapes");
arl.add("Mango");
arl.add("Guava");
CopyOnWriteArrayList in java:
We have 3 constructors :
It creates an empty list in memory. This constructor is useful when we want to create a list without
any value.
2) CopyOnWriteArrayList c = new CopyOnWriteArrayList(Collection c);
Interconversion of collections.
3) CopyOnWriteArrayList c = new CopyOnWriteArrayList(Object[] obj) ;
It Creates a list that containing all the elements that is specified Array. This constructor is useful when
we want to create a CopyOnWriteArrayList from Array.
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
//Iterator1
Iterator<String> iterator1 = copyOnWriteList.iterator();
//Iterator2
Iterator<String> iterator2 = copyOnWriteList.iterator();
import java.util.*;
import java.util.concurrent.*;
class ConcurrentModification extends Thread
{
CopyOnWriteArrayList<String> al = null;
public ConcurrentModification(CopyOnWriteArrayList<String> al)
{
this.al = al;
}
@Override
public void run()
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
}
al.add("KIWI");
}
}
public class CopyOnWriteArrayListExample2
{
public static void main(String[] args) throws InterruptedException
{
CopyOnWriteArrayList<String> arl = new CopyOnWriteArrayList<>();
arl.add("Apple");
arl.add("Orange");
arl.add("Grapes");
arl.add("Mango");
arl.add("Guava");
ConcurrentModification cm = new ConcurrentModification(arl);
cm.start();
}
Naresh i Technology
We can use CopyOnWriteArrayList rather than the ArrayList for following cases
1. Thread safe
The CopyOnWriteArrayList is thread safe version of ArrayList. If we want to work in multithread
environment then we should choose the CopyOnWriteArrayList. Because we can perform read and
write operation by multiple threads at a time.
Reason: Because ArrayList is not thread safe. In ArrayList different threads make different changes
that leads to inaccuracy of data. But in case of CopyOnWriteArrayList, whenever any thread makes
changes in the original list, the JVM creates a new copy of list internally. So that value is updated for
the all threads.
Note: In CopyOnWriteArrayList only one thread can perform write operation at a time But multiple
threads can perform read operations simultaneously
Reason: For example we are creating a list from CopyOnWriteArrayList that contains 1000 objects.
CopyOnWriteArrayList<String> copyOnWriteList = new
CopyOnWriteArrayList<String>(listOfthousands);
copyOnWriteList.add("Ankit");
copyOnWriteList.add("ELina");
Each time, The JVM creates a new fresh copy of list. It means JVM creates three new copies for three
operations. Now we can think if we are doing number of modification in list it will be very costly.
CopyOnWriteArraySet :
It creates a new copy of the array every time iterator is created, so performance is slower
than HashSet.
Constructors:
import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.CopyOnWriteArraySet;
}
}
ConcurrentHashMap:
Like HashMap and Hashtable, the ConcurrentHashMap is also used Hashtable data structure.
But it is using the segment locking strategy to handle the multiple threads. A
segment(bucket) is a portion of ConcurrentHashMap and ConcurrentHashMap uses a
separate lock for each thread. Unlike Hashtable or synchronized HashMap, it doesn t
synchronize the whole HashMap or Hashtable for one thread.
As we have seen in the internal implementation of the HashMap, the default size of
HashMap is 16 and it means there are 16 buckets. The ConcurrentHashMap uses the same
concept is used in ConcurrentHashMap. It uses the 16 separate locks for 16 buckets by
default because the default concurrency level is 16. It means a ConcurrentHashMap can be
used by 16 threads at same time. If one thread is reading from one bucket(Segment), then
the second bucket doesn t affect it.
As we know Hashtable and HashMap works based on key-value pairs. But why we are introducing
another Map? As we know HashMap is not thread safe, but we can make it thread-safe by using
Collections.synchronizedMap() method and Hashtable is thread-safe by default.
But a synchronized HashMap or Hashtable is accessible only by one thread at a time because the
object get the lock for the whole HashMap or Hashtable. Even multiple threads can t perform read
operations at the same time. It is the main disadvantage of Synchronized HashMap or Hashtable,
which creates performance issues. So ConcurrentHashMap provides better performance than
Synchronized HashMap or Hashtable.
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
cityTemperatureMap.put("Delhi", "30");
cityTemperatureMap.put("Mumbai", "32");
cityTemperatureMap.put("Chennai", "35");
cityTemperatureMap.put("Bangalore", "22" );
while (iterator.hasNext())
{
System.out.println(cityTemperatureMap.get(iterator.next()));
// adding new value, it won't throw error
cityTemperatureMap.put("Hyderabad", "28");
}
}