Module v Java
Module v Java
Collection Framework
2. Set Interface
The Set interface allows us to store elements in different sets similar to the
set in mathematics. It cannot have duplicate elements.
3. Queue Interface
The Queue interface is used when we want to store and access elements
in First In, First Out(FIFO) manner.
Graphical representation of Collection's interfaces
Graphical representation of Map’s interfaces
Iterable Interface
• In Java ,there is now an iterable interface (java.lang.Iterable).
It is the root interface of the Java collection Classes. The
collection interface extends iterable, so all subtypes of
Collection also implement the iterable interface.
• The Syntax of the Iterable interface is given below
public interface Iterable<T>
• A collection provide an iterator which allows a sequential
access to the element of collection. An iterator can be
obtained by calling the following method of collection
interface:
public Iterator iterator()
(Or)
public interface Iterable<T> {
public Iterator<T> iterator();
}
Methods of Iterator
• public boolean hasNext()
• public Object next()
• public Object remove()
ListIterator Interface
• This is the subinterface of iterator.which allows the programmer to
travel in the list in either direction and make modifications to the
underlying list
Methods of ListIterator
• public boolean hasNext()
• public boolean hasPrevious()
• public Object next()
• public Object previous()
• public Int nextIndex()
• public Int previousIndex()
• public void remove()
• public void add(Object o)
• public void set(Object o)
Collection Interface
Vector
List (Duplicate elements but in A sequence of elements that
ArrayList
insertion order) need not be unique.
LinkedList
Method Description
It is used to add the specified element in
boolean add(Object o)
this set.
This method adds all the elements in the
boolean addAll(Collection c)
given collection.
It is used to get the number of elements in
int size()
the set.
This method checks that the set is empty
boolean isEmpty()
or not.
It is used to remove all the elements from
void clear()
the set.
This method returns true if this set
boolean contains(Object o)
contains the given element.
Method Description
This method returns true if this set
boolean containsAll(Collection c) contains all the elements of the given
collection.
It is used to remove the specified element
boolean remove(Object o)
from this set.
It removes all the elements in the given
boolean removeAll(Collection c)
collection from the set.
It returns an Iterator over the elements in
Iterator iterate()
this set.
It is used to compare the given element
boolean equals(Object o)
for equility in this set.
It is used to get the hashCode value for
int hashCode()
this set.
Example-2
package iterateSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class IterateSetEx
{
public static void main(String[] args)
{
// Create a generic set object of type String.
Set<String> s = new HashSet<String>(); // s.size() is 0.
int size = s.size();
System.out.println("Size before adding elements: " +size);
s.add("Orange"); // s.size() is 1.
s.add("Red"); // s.size() is 2.
s.add("Blue"); // s.size() is 3.
s.add("Yellow"); // s.size() is 4.
s.add("Green"); // s.size() is 5.
System.out.println("Elements in set");
System.out.println(s);
s.remove("Blue");
System.out.println("Set elements after removing");
System.out.println(s);
boolean search = s.contains(“Blue”);
System.out.println("Is Element A present in set: " +search);
Iterator<String> itr = s.iterator();
System.out.println("Iteration using Iterator
method");
while(itr.hasNext())
{
Object str = itr.next();
System.out.println(str);
}
}}
When to use Set?
There are four types of iterators or cursors available in Java. They are as follows:
Enumeration
Iterator
ListIterator
Spilterator
Enumeration in Java
• Enumeration is the first iterator that was introduced in Java 1.0
version. It is located in java.util package. It is a legacy interface that
is implemented to get elements one by one from the legacy
collection classes such as Vector and Properties.
• Legacy classes are those classes that are coming from the first
version of Java. Early versions of Java do not include collections
framework. Instead, it defined several classes and one interface for
storing objects.
• When collections came in the Java 1.2 version, several of the
original classes were re-engineered to support the collection
interfaces.
• Thus, they are fully compatible with the framework. These old
classes are known as legacy classes. The legacy classes defined by
java.util are Vector, Hashtable, Properties, Stack, and Dictionary.
There is one legacy interface called Enumeration.
• Enumeration is read-only. You can just read data from the vector.
You cannot remove it from the vector using Enumeration.
How to create Enumeration object in
Java?
• Since enumeration is an interface so we cannot create an
object of enumeration directly. We can create an object of
enumeration by calling elements() method of the Vector class.
• The syntax for creating an object of enumeration in java is as
follows:
• Syntax:
public Enumeration elements() // Return type is Enumeration.
For example:
Enumeration e = v.elements(); // Here, v is a vector class object.
Methods of Enumeration in Java
• The Enumeration interface defines the following two
methods. They are as follows:
1. public boolean hasMoreElements(): When this method is
implemented, hasMoreElements() will return true If there are
still more elements to extract and false if all the elements
have been enumerated.
2. public Object nextElement(): The nextElement() method
returns next element in the enumeration. It will throw
NoSuchElementException when the enumeration is complete.
Example
import java.util.Enumeration;
import java.util.Vector;
public class EnumerationTest
{
public static void main(String[] args)
{ // Create an object of vector class using generic.
Vector<Integer> v = new Vector<Integer>();
for(int i=0; i<=10; i++)
{
v.addElement(i);
}
System.out.println(v);
Enumeration e = v.elements();
while(e.hasMoreElements())
{
// Direct type casting in one step.
Integer i = (Integer)e.nextElement();
System.out.println(i);
}
Enumeration en = v.elements();
while(en.hasMoreElements())
{ Integer it = (Integer)en.nextElement();
if(it % 2 == 0)
{ System.out.println(it);
}}}}
• Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
0 1 2 3 4 5 6 7 8 9 10 0 2 4 6 8 10
• There are many limitations of using enumeration interface
in java. They are as follows:
1. Enumeration concept is applicable for only legacy class.
Hence, it is not a universal cursor.
2. We can get only read operation by using the
enumeration. We cannot perform the remove operation.
3. We can iterate using enumeration only in the forward
direction.
4. Java is not recommended to use enumeration in new
projects.
To overcome these limitations, We should go for the next level
Iterator concept in Java.
Iterator in Java
• An iterator in Java is a special type of object that provides
sequential (one by one) access to the elements of a
collection object.
• In simple words, it is an object that allows us to get and
process one element at a time. It is introduced in Java 1.2
Collections Framework.
• An Iterator object implements Iterator interface which is
present in java.util.Iterator package. Therefore, to use an
Iterator, you must import either java.util.Iterator or
java.util.*.
• Iterator in Java is used in the Collection Framework to
retrieve elements sequentially (one by one). It is
called universal Iterator or cursors.
• It can be applied to any collection object. By using Iterator,
we can perform both read and remove operations.
How to create Iterator object in Java?
• Iterator object can be created by calling iterator() method
which is present in the iterable interface. The general syntax
for creating Iterator object is as follows:
a) Iterator itr = c.iterator(); // c is any collection object.
b) Iterator<Type> itr = c.iterator(); // Generic type.
For example:
Iterator<String> itr = c.iterator();
Iterator<Integer> itr = c.iterator();
import java.util.ArrayList;
import java.util.Iterator;
public class IteratorTest
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
// Adding elements in the array list.
al.add("A");
al.add("B");
al.add("C");
al.add("D");
al.add("E");
al.add("F");
Iterator<String> itr = al.iterator();
while (itr.hasNext())
{
String str = itr.next();
System.out.print(str + " ");
}}}
LinkedList in Java
• LinkedList in Java is a linear data structure that uses a doubly linked
list internally to store a group of elements.
• A doubly linked list consists of a group of nodes that together
represents a sequence in the list. It stores the group of elements in
the sequence of nodes.
• Each node contains three fields: a data field that contains data
stored in the node, left and right fields contain references or
pointers that point to the previous and next nodes in the list.
• A pointer indicates the addresses of the next node and the previous
node. Elements in the linked list are called nodes.
• Since the previous field of the first node and the next field of the
last node do not point to anything, we must set it with the null
value.
• LinkedList in Java is a very convenient way to store elements (data).
When we store a new element in the linked list, a new node is
automatically created.
• Its size will grow with the addition of each and every
element. Therefore, its initial capacity is zero. When an
element is removed, it will automatically shrink.
• Adding elements into the LinkedList and removing
elements from the LinkedList are done quickly and take the
same amount of time (i.e. constant time).
• So, it is especially useful in situations where elements are
inserted or removed from the middle of the list.
• In the Linked List, the elements are not stored in the
consecutive memory location. An element (often called
node) can be located anywhere in the free space of the
memory by connecting each other using the left and right
sides of the node portion.
• Thus, it avoids the rearrangement of elements required but
requires that each element is connected to the next and
previous by a link.
• Therefore, a LinkedList is often a better choice if elements are
added or removed from intermediate locations within the list.
• The right side of the node contains the address of the next
element and the left side of the node contains the address of
the previous element in the list.
Java LinkedList Constructors
• Like ArrayList class, Java LinkedList class consists of two
constructors.
1.LinkedList() - It is used to create an empty LinkedList object.
2.LinkedList(Collection c) - It is used to construct a list containing
the elements of the given collection.
We can create an empty linked list object for storing String type
elements (objects) as:
LinkedList<String> llist = new LinkedList<String>(); // An empty
list.
Features of LinkedList class
The main features of the Java LinkedList class are as
follows:
1. The underlying data structure of LinkedList is a doubly
LinkedList data structure. It is another concrete
implementation of the List interface like an array list.
2. Java LinkedList class allows storing duplicate elements.
3. Null elements can be added to the linked list.
4. Heterogeneous elements are allowed in the linked list.
5. Java LinkedList is not synchronized. So, multiple
threads can access the same LinkedList object at the
same time. Therefore, It is not thread-safe. Since
LinkedList is not synchronized. Hence, its operation is
faster.
6. Insertion and removal of elements in the LinkedList are fast because,
in the linked list, there is no shifting of elements after each adding
and removal. The only reference for next and previous elements
changed.
7. LinkedList is the best choice if your frequent operation is insertion or
deletion in the middle.
8. Retrieval (getting) of elements is very slow in LinkedList because it
traverses from the beginning or ending to reach the element.
9. The LinkedList can be used as a “stack“. It has pop() and push()
methods which make it function as a stack.
10. Java LinkedList does not implement random access interface. So,
the element cannot be accessed (getting) randomly. To access the
given element, we have to traverse from the beginning or ending to
reach elements in the LinkedList.
11. We can iterate linked list elements by using ListIterator.
How does Insertion work in Java LinkedList?
In the Java LinkedList, we can perform insertion (addition) operations without
affecting any of data items already stored in the list. Let’s take an example to
understand this concept.
1. Let us assume that our initial LinkedList has the following data as shown in the
below figure.
2. Now we will perform insertion operation on this linked list. We
will add an element G at index position 2 using add() method.
The syntax for adding element G is as follow:
linkedlist.add(2,"G");
When the insertion operation takes place in the linked list,
internally, LinkedList will create one node with G element at
anywhere available space in the memory and changes the
next and previous pointer only without shifting of any
element in the list.
How does Deletion work in Java LinkedList?
1. Let us assume that our initial LinkedList has the following data.
2. We will perform deletion operations on this LinkedList.
Suppose we want to remove or delete element B from index
position 1. The syntax to delete element B is as follows:
• linkedlist.remove(1);When deletion operation takes place, the
node with element B is deleted with changing the next and
previous pointer. The deleted node becomes unused memory.
• Therefore, Java will clean up the unused memory space using
the garbage collection.
LinkedList Methods in Java
SN Method Description
It is used to add the specified element
1. boolean add(Object o)
to the end of a list.
It is used to insert the specified
2. void add(int index, Object o) element at the specified position in a
list.
It is used to add all of the elements in
3. boolean addAll(Collection c) the specified collection to the end of
this list
It is used to add all the elements of the
4. boolean addAll(int index, Collection c) specified collection at specified index
position in the list.
It is used to remove or delete all the
5. void clear()
elements from a list.
It returns true if a list contains a
6. boolean contains(Object o)
specified element.
It is used to get the number of
7. int size()
elements in a list.
SN Method Description
It returns an array containing all the
8. Object[] toArray()
elements in a list in proper sequence
This method is used to return a shallow copy
9. Object clone()
of an ArrayList.
This method is used to remove the first
10. boolean remove(Object o) occurrence of the specified element in the
linked list.
This method is used to remove the element
11. Element remove(int index)
at the specified position in the linked list.
This method is used to retrieve the first
12. Element element()
element of the linked list.
It is used to get the element at the specified
13. E get(int index)
position in a list.
It is used to replace the element at the
14. Element set(int index, E element) specified position in a list with the specified
element.
SN Method Description
import java.io.*;
import java.util.*;
class List1 {
public static void main(String[] args)
{
// Size of the LinkedList
int n = 5;
import java.io.*;
import java.util.*;
class Vector1 {
public static void main(String[] args)
{
// Size of the vector
int n = 5;
import java.io.*;
import java.util.*;
class Stack1 {
public static void main(String[] args)
{
// Size of the stack
int n = 5;
Output:
Roll No: 404, Name: Mark
Roll No: 101, Name: John
Roll No: 505, Name: Maya
Roll No: 202, Name: Ricky
Roll No: 303, Name: Deep
HashMap in Java
• HashMap<K, V> is a part of Java’s collection since Java 1.2.
This class is found in java.util package.
• In simpler terms, HashMap<K, V> is a data structure that
stores elements in the form of a key-value pair.
• These key-value pairs are also termed as an Entry of
HashMap.
• Keys are unique, and duplicate keys are not allowed.
• It stores values based on keys, and it can be accessed using
keys.
• Hashmap allows multiple null values and only one null key.
• HashMaps are non-synchronized, meaning that they are not
thread-safe. If multiple threads access the hashmap at the
same time, they will modify the map structurally.
• HashMaps are an unordered collection of key-value pairs.
They do not maintain the insertion order.
• They are much faster in terms of retrieving data as compared
to arrays and linked-list, with constant time performance for
the basic operations.
• Its initial default capacity(number of elements that can be
stored) of hashmap is 16, and the default load factor is 0.75.
CONSTRUCTORS IN HASHMAP
• There are four constructors of the hashmap, all of which have
public access specifiers.
1. Hashmap()
• It is the default constructor that creates an instance of a
hashmap with the initial capacity of
• 16 and load factor 0.75.
HashMap<K,V> hm = new HashMap<K,V>();
2. HashMap(int initialCapacity)
• This constructor creates an instance of a hashmap with the
specified initial capacity and
• default load factor 0.75.
HashMap<K,V> hm = new HashMap<K,V>(int initialCapacity);
3. HashMap(int initialCapacity, float loadFactor)
• This constructor creates an instance of a hashmap with the
specified initial capacity and the
• specified load factor.
HashMap<K,V> hm = new HashMap<K,V>(int initialcapacity, float
loadfactor);
4. HashMap(Map map)
• This constructor creates an instance of a hashmap with
similar mappings as the given Map.
HashMap<K,V> hm = new HashMap<K,V>(Map m);
Example-1
import java.io.*;
import java.util.*;
public class Hashmap
{
public static void main(String args[])
{
HashMap<String, Integer> hm = new HashMap<String, Integer>(5,0.75f);
hm.put("Red",1);
hm.put("Blue",2);
hm.put("Green",3);
hm.put("Yellow",4);
System.out.println(hm);
}}
Example-2
import java.io.*;
import java.util.*;
public class Hashmap
{
public static void main(String args[])
{ Map<String, Integer> hm = new HashMap<String, Integer>();
hm.put("Red",1);
hm.put("Blue",2);
hm.put("Green",3);
hm.put("Yellow",4);
System.out.println(hm);
HashMap<String, Integer> hm1 = new HashMap<String, Integer>(hm);
System.out.println(hm1);
}}
• Output :
{Red=1, Blue=2, Yellow=4, Green=3}
{Red=1, Blue=2, Yellow=4, Green=3}
Methods of HashMap
• These are various important hashmap class methods.
1.put(): java.util.HashMap.put() plays role in associating the
specified value with the specified key in this map. If the map
previously contained a mapping for the key, the old value is
replaced.
Syntax:
public V put(K key,V value)
2.get(): java.util.HashMap.get()method returns the value to
which the specified key is mapped, or null if this map contains
no mapping for the key.
Syntax:
public V get(Object key)
3. isEmpty(): java.util.HashMap.isEmpty() method returns true if the
map contains no key-value mappings.
Syntax:
public boolean isEmpty()
4. size(): java.util.HashMap.size() returns the number of key-value
mappings in this map.
Syntax:
public int size()
5. The remove(K) method takes the key as the argument and deletes
the entry for the given key if it is present on the map. We also have
one more remove(K, V) method to delete the entry.
6. Access one particular value associated with a key using get(K)
The value present in a hashmap can be accessed using the
method get(K). The key must be passed in the argument, and the
value stored in that key will be fetched.
7. Access only the keys of elements
If you want to retrieve only the set of keys, the keySet() method will
return just the set of keys in hashmaps.
8. Access only the values of elements
The values() method helps to obtain the set of values.
9. Access the entries of HashMap
The entrySet() method will return the set of entries(<K, V>) in a
hashmap.
10. Traverse the HashMap
After knowing how to access the elements in a hashmap, let us see
how to iterate or traverse the hashmap.
The idea is to iterate over the set of entries using the for-each loop and
then access the key and values in an entry using
the getKey() and getValue() methods.
We use Map.Entry(K, V) that allows us to access the entries of a map.
11. Update the value
• If you want to update the value stored in a given key, you can
either use put(K, V) or
• replace(k,v) method.
import java.io.*;
import java.util.*;
public class Hashmap
{
public static void main(String args[])
{
HashMap<String, Integer> hm = new HashMap<String,
Integer>();
hm.put("Red",1);
hm.put("Blue",2);
hm.put("Green",3);
hm.put("Yellow",4);
System.out.println(hm);
System.out.println(hm.entrySet()); } }
• Output :
{Red=1, Blue=2, Yellow=4, Green=3}
[Red=1, Blue=2, Yellow=4, Green=3]
Linked HashMap
• LinkedHashMap in Java is a concrete class that is HashTable and
LinkedList implementation of Map interface. It stores entries using a
doubly-linked list.
• Java LinkedHashMap class extends the HashMap class with a linked-list
implementation that supports an ordering of the entries in the map.
• LinkedHashMap in Java was added in JDK 1.4 version. It is exactly the
same as HashMap (including constructors and methods) except for the
following differences:
1. The underlying data structure of HashMap is HashTable whereas, the
underlying data structure of LinkedHashMap is HashTable and LinkedList
(Hybrid data structure).
2. Insertion order is not preserved in the HashMap because it is based on
the hashCode of Key. But in the case of LinkedHashMap, the insertion
order of elements is preserved because it is based on the Key insertion
order, that is, the order in which keys are inserted in the map.
3. HashMap was introduced in Java 1.2 version whereas, LinkedHashMap
was introduced in Java 1.4 version.
LinkedHashMap class declaration
• LinkedHashMap is a generic class that is present in
java.util.LinkedHashMap package. It has the following
declaration.
public class LinkedHashMap<K,V> extends HashMap<K,V>
implements Map<K,V>
• Here, K defines the type of keys, and V defines the type of
values.
Features of LinkedHashMap in Java
• There are several features of LinkedHashMap in Java that should
keep in mind. They are as follows:
1. The underlying data structure of LinkedHashMap is HashTable
and LinkedList.
2. Java LinkedHashMap maintains the insertion order. The entries in
Java LinkedHashMap can be retrieved either in the order in which
they were inserted into the map (known as insertion order) or in
the order in which they were last accessed, from least to most
recently accessed.
3. LinkedHashMap contains unique elements. It contains values based
on keys.
4. LinkedHashMap allows only one null key but can have multiple null
values.
5. LinkedHashMap in Java is non synchronized. That is,
multiple threads can access the same LinkedHashMap object
simultaneously.
6. The default initial capacity of LinkedHashMap class is 16 with a load
factor of 0.75.
Constructors of Java LinkedHashMap class
• Java LinkedHashMap class has the following constructors.
They are as follows:
1. LinkedHashMap(): This constructor is used to create a default
LinkedHashMap object. It constructs an empty insertion-
ordered LinkedHashMap object with the default initial
capacity 16 and load factor 0.75.
• The general syntax to construct default LinkedHashMap object
is as follows:
• LinkedHashMap lhmap = new LinkedHashMap(); or,
LinkedHashMap<K,V> lhmap = new LinkedHashMap<>(); //
Generic form
2. LinkedHashMap(int initialCapacity): It is used to create an
empty insertion-ordered LinkedHashMap object with the
specified initial capacity and a default load factor of 0.75. The
general syntax in generic form is as follows:
LinkedHashMap<K,V> lhmap = new LinkedHashMap<>(int
initialCapacity);
3. LinkedHashMap(int initialCapacity, float loadFactor): It is
used to create an empty insertion-ordered LinkedHashMap
object with the specified initial capacity and load factor. The
general syntax in generic form is given below:
LinkedHashMap<K,V> lhmap = new LinkedHashMap<>(int
initialCapacity, float loadFactor);
For example: LinkedHashMap<String, Integer> lhmap = new
LinkedHashMap<>(16, 0.75f);
4. LinkedHashMap(Map m): This constructor is used to create an
insertion-ordered LinkedHashMap object with the elements
from the given Map m.
5. LinkedHashMap(int initialCapacity, float loadFactor, boolean
accessOrder): This constructor is used to create an empty
LinkedHashMap instance with the specified initial capacity,
load factor, and ordering mode.
• If accessOrder is true, access-order is used. If it is false, the
insertion order is used.
• The general syntax to create LinkedHashMap object with
three arguments of constructor is as follows:
LinkedHashMap<K,V> lhmap = new LinkedHashMap<int
initialCapacity, float loadFactor, boolean accessOrder>();
For example:
1.LinkedHashMap<String, String> lhmap = new
LinkedHashMap<>(16, 0.75f, true); // For access order.
2.LinkedHashMap<String, String> lhmap = new
LinkedHashMap<>(16, 0.75f, false); // For insertion order
LinkedHashMap Methods in Java
• The methods of LinkedHashMap are exactly the same as HashMap
class methods, except for one method that is added by
LinkedHashMap. This method is removeEldestEntry().
• The general syntax for this method is as follows:
protected boolean removeEldestEntry(Map.Entry<K,V> e)
• The parameter e is the least recently added entry in the map, or if it
is an access-ordered map, the least recently accessed entry.
• This method returns true if the map removes this eldest (oldest)
entry. If this entry is retained, or not removed, this method returns
false.
• The removeEldestEntry() method is called by put() and putAll() after
adding a new entry into the map. It helps to remove the eldest
entry each time when a new entry is added.
• This method is useful if the map represents a cache. It allows the
map to reduce memory consumption by deleting stale entries.
Example
import java.util.LinkedHashMap;
public class LinkedHashMapEx1
{
public static void main(String[] args)
{ // Create a LinkedHashMap instance.
LinkedHashMap<String, Integer> lhmap = new
LinkedHashMap<>();
// Checking the size of linked hash map before adding entries.
int size = lhmap.size();
System.out.println("Size of LinkedHashMap before adding
entries: " +size);
// Checking linked hash map is empty or not before adding
//entries.
boolean isEmpty = lhmap.isEmpty();
System.out.println("Is LinkedHashMap empty: " +isEmpty);
// Adding entries in linked hash map.
lhmap.put("John", 30);
lhmap.put("Peter", 25);
lhmap.put("Ricky", 23);
lhmap.put("Deep", 28);
lhmap.put("Mark", 32);
System.out.println("Display entries in LinkedHashMap");
System.out.println(lhmap); int size2 = lhmap.size();
System.out.println("Size of LinkedHashMap after adding
entries: " +size2);
// Adding null as key and value.
lhmap.put(null, null);
System.out.println(lhmap);
}
• Output:
Size of LinkedHashMap before adding entries: 0
Is LinkedHashMap empty: true
Display entries in LinkedHashMap
{John=30, Peter=25, Ricky=23, Deep=28, Mark=32}
Size of LinkedHashMap after adding entries: 5
{John=30, Peter=25, Ricky=23, Deep=28, Mark=32, null=null}
• When to use LinkedHashMap in Java?
• LinkedHashMap can be used when you want to preserve the
insertion order. Java LinkedHashMap is slower than HashMap
but it is suitable when more number of insertions and
deletions happen.
• Which implementation is better to use: HashMap or
LinkedHashMap?
• Both HashMap and LinkedHashMap classes provide
comparable performance but HashMap is a natural choice if
the ordering of elements is not an issue.
• Adding, removing, and finding entries in a LinkedHashMap is
slightly slower than in HashMap because it needs to maintain
the order of doubly linked list in addition to the hashed data
structure.
TreeMap in Java
• TreeMap in Java is a concrete class that is a red-black tree based
implementation of the Map interface.
• It provides an efficient way of storing key/value pairs in sorted
order automatically and allows rapid retrieval. It was added in JDK
1.2 and present in java.util.TreeMap.
• A TreeMap implementation provides guaranteed log(n) time
performance for checking, adding, retrieval, and removal
operations.
• The two main difference between HashMap and TreeMap is that
HashMap is an unordered collection of elements while TreeMap
is sorted in the ascending order of its keys. The keys are sorted
either using Comparable interface or Comparator interface.
• HashMap allows only one null key while TreeMap does not allow
any null key.
TreeMap class declaration
• equals(Object obj):
a method provided by java.lang.Object that indicates whether
some other object passed as an argument is "equal to" the
current instance. The default implementation provided by the
JDK is based on memory location — two objects are equal if
and only if they are stored in the same memory address.
• hashcode():
a method provided by java.lang.Object that returns an integer
representation of the object memory address. By default, this
method returns a random integer that is unique for each
instance. This integer might change between several executions
of the application and won't stay the same.
The Contract Between equals() and hashcode()
• It is generally necessary to override the hashCode() method
whenever equals() method is overridden, so as to maintain the general
contract for the hashCode() method, which states that equal objects
must have equal hash codes.
• Whenever it is invoked on the same object more than once during an
execution of a Java application, the hashCode method must consistently
return the same integer, provided no information used
in equals comparisons on the object is modified.
This integer need not remain consistent from one execution of an
application to another execution of the same application.
• If two objects are equal according to the equals(Object) method, then
calling the hashCode method on each of the two objects must produce
the same integer result.
• It is not required that if two objects are unequal according to
the equals(java.lang.Object) method, then calling the hashCode method
on each of the two objects must produce distinct integer results.
However, the programmer should be aware that producing distinct
integer results for unequal objects may improve the performance of
hash tables.
Example
public class Student
{
private int id;
private String name;
public Student(int id, String name)
{
this.name = name;
this.id = id;
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}}
public class HashcodeEquals
{
public static void main(String[] args)
{
Student alex1 = new Student(1, "Alex");
Student alex2 = new Student(1, "Alex");
System.out.println("alex1 hashcode = " + alex1.hashCode());
System.out.println("alex2 hashcode = " + alex2.hashCode());
System.out.println("Checking equality between alex1 and
alex2 = " + alex1.equals(alex2));
}}
• Output:
alex1 hashcode = 1852704110
alex2 hashcode = 2032578917
Checking equality between alex1 and alex2 = false
• Although the two instances have exactly the
same attribute values, they are stored in
different memory locations. Hence, they are
not considered equal as per the default
implementation of equals(). The same applies
for hashcode() — a random unique code is
generated for each instance.
Overriding equals()
• For business purposes, we consider that two students are
equal if they have the same ID, so we override
the equals() method and provide our own implementation as
the following:
@Override
public boolean equals(Object obj)
{
if (obj == null)
return false;
if (!(obj instanceof Student))
return false;
if (obj == this)
return true;
return this.getId() == ((Student) obj).getId();}
• In the above implementation, we are saying that two students
are equal if and only if they are stored in the same memory
address OR they have the same ID. Now if we try to
run HashcodeEquals, we will get the following output:
alex1 hashcode = 2032578917
alex2 hashcode = 1531485190
Checking equality between alex1 and alex2 = true
• As you noticed, overriding equals() with our custom business
forces Java to consider the ID attribute when comparing
two Student objects.
Overriding hashcode()
• equals() With HashSet
• We want to store all the students in a HashSet, so we
update HashcodeEquals as the following: