0% found this document useful (0 votes)
2 views82 pages

Java Collections Framework

The document provides an overview of the Java Collections Framework, detailing various collection types such as List, Set, Queue, and Map, along with their implementations like ArrayList, LinkedList, HashSet, and HashMap. It highlights key characteristics, methods, and example usages of ArrayList and LinkedList, explaining when to use each based on performance needs. Additionally, it briefly mentions Vector as a legacy class with thread safety features.

Uploaded by

sivaramans
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views82 pages

Java Collections Framework

The document provides an overview of the Java Collections Framework, detailing various collection types such as List, Set, Queue, and Map, along with their implementations like ArrayList, LinkedList, HashSet, and HashMap. It highlights key characteristics, methods, and example usages of ArrayList and LinkedList, explaining when to use each based on performance needs. Additionally, it briefly mentions Vector as a legacy class with thread safety features.

Uploaded by

sivaramans
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 82

Java Collections Framework: List: ArrayList, LinkedList, Set: HashSet, TreeSet,

Map: HashMap, TreeMap, Queue: PriorityQueue.

Generics: Generic Classes and Methods.

Exploring Java Collections: A


Guide to Lists, Sets, Queues,
and Maps
Collections are a fundamental part of the Java Collections
Framework, which provides a unified architecture for
storing and manipulating groups of objects. The framework
includes various interfaces and classes that allow you to
work with different types of collections, such as lists, sets,
queues, and maps. Here’s an overview of the main
components:
Press enter or click to view image in full size
1. Collection : The root interface of the collection
hierarchy. It defines the most common methods for
collections, such as add, remove, contains, size,

and iterator.

2. List : An ordered collection (also known as a


sequence). It allows duplicate elements and provides
positional access and insertion of elements.
 ArrayList : Resizable-array implementation of
the List interface.

 LinkedList : Doubly-linked list implementation of


the List interface.

 Vector : Synchronized resizable-array implementation


of the List interface

3. Set : A collection that does not allow duplicate


elements.

 HashSet : Implementation of the Set interface backed


by a hash table.

 LinkedHashSet : Hash table and linked list


implementation of the Set interface, with predictable
iteration order.

 TreeSet : Implementation of the Set interface that


uses a tree for storage, providing sorted order.

4. Queue : A collection designed for holding elements


prior to processing.

 PriorityQueue : An unbounded queue based on a


priority heap.

 LinkedList : Can be used as a queue.


5. Deque : A linear collection that supports element
insertion and removal at both ends.

 ArrayDeque : Resizable-array implementation of


the Deque interface.

 LinkedList : Can be used as a deque

6. Map : An object that maps keys to values. A Map cannot


contain duplicate keys; each key can map to at most one
value.

 HashMap : Implementation of the Map interface


backed by a hash table.

 LinkedHashMap : Hash table and linked list


implementation of the Map interface, with predictable
iteration order.

 TreeMap : Implementation of the Map interface that


uses a tree for storage, providing sorted order.

 Hashtable : Synchronized implementation of


the Map interface.

ArrayList

ArrayList is a part of the Java Collections Framework and


is found in the java.util package. It is a resizable
array implementation of the List interface. Unlike arrays,
which have a fixed size, ArrayList can grow and shrink
dynamically as elements are added or removed.

Key Characteristics:

1. Dynamic Size: Unlike arrays, ArrayList can


automatically resize itself when elements are added
or removed.

2. Order of Elements: It maintains the order of


insertion, meaning elements are stored in the order
in which they are added.

3. Random Access: Elements can be accessed directly


using indexes, offering fast random access to
elements.

4. Null Values: ArrayList allows null values.

5. Not Thread-Safe: It is not synchronized, meaning


multiple threads modifying
the ArrayList simultaneously may lead to
unpredictable results unless explicitly synchronized.

Basic Syntax:

import java.util.ArrayList;

ArrayList<Type> list = new ArrayList<>();

Commonly Used Constructors:


 ArrayList(): Creates an empty list with an initial
capacity of 10.

 ArrayList(Collection<? extends E> c): Creates a list


initialized with the elements of the given collection.

 ArrayList(int initialCapacity): Creates an empty list with


the specified initial capacity.

Methods in ArrayList

Below is a list of commonly used methods in ArrayList:

 add(E e): Appends the specified element to the end of


this list.

 add(int index, E element): Inserts the specified element at


the specified position in this list.

 get(int index): Returns the element at the specified


position in this list.

 set(int index, E element): Replaces the element at the


specified position in this list with the specified
element.

 remove(int index): Removes the element at the specified


position in this list.

 remove(Object o): Removes the first occurrence of the


specified element from this list.

 clear(): Removes all of the elements from this list.


 contains(Object o): Returns true if this list contains the
specified element.

 indexOf(Object o): Returns the index of the first


occurrence of the specified element.

 lastIndexOf(Object o): Returns the index of the last


occurrence of the specified element.

 isEmpty(): Returns true if this list contains no elements.

 size(): Returns the number of elements in this list.

 toArray(): Returns an array containing all of the


elements in this list.

 subList(int fromIndex, int toIndex): Returns a view of the


portion of this list between fromIndex, inclusive,
and toIndex, exclusive.

 sort(Comparator<? super E> c): Sorts the list according to


the order induced by the specified comparator.

 binarySearch(List<? extends T> list, T key): Searches the


specified list for the specified object using the binary
search algorithm (requires the list to be sorted first).

 iterator(): Returns an iterator over the elements in this


list.

 listIterator(): Returns a list iterator over the elements in


this list.
 stream(): Returns a sequential stream with this list as
its source.

 forEach(Consumer<? super E> action): Performs the given


action for each element of the list.

 addAll(Collection<? extends E> c): Appends all of the


elements in the specified collection to the end of this
list.

 removeAll(Collection<?> c): Removes from this list all of


its elements that are contained in the specified
collection.

 retainAll(Collection<?> c): Retains only the elements in


this list that are contained in the specified collection.

 removeIf(Predicate<? super E> filter): Removes all


elements of this list that satisfy the given predicate.

Example Usage of ArrayList

import java.util.ArrayList;

public class ArrayListExample {


public static void main(String[] args) {
// Creating an ArrayList of String type
ArrayList<String> fruits = new ArrayList<>();

// Adding elements to the ArrayList


fruits.add("Apple");
fruits.add("Banana");
fruits.add("Mango");
System.out.println("Fruits List: " + fruits);

// Adding an element at a specific index


fruits.add(1, "Orange");
System.out.println("After adding Orange at index 1: " + fruits);
// Accessing an element at a specific index
String fruit = fruits.get(2);
System.out.println("Element at index 2: " + fruit);

// Removing an element from the ArrayList


fruits.remove("Banana");
System.out.println("After removing Banana: " + fruits);

// Finding the index of an element


int index = fruits.indexOf("Mango");
System.out.println("Index of Mango: " + index);

// Checking if an element exists


boolean containsApple = fruits.contains("Apple");
System.out.println("Does the list contain Apple? " +
containsApple);

// Replacing an element
fruits.set(2, "Pineapple");
System.out.println("After replacing Mango with Pineapple: " +
fruits);

// Getting the size of the ArrayList


int size = fruits.size();
System.out.println("Size of the list: " + size);

// Checking if the list is empty


boolean isEmpty = fruits.isEmpty();
System.out.println("Is the list empty? " + isEmpty);

// Clearing the list


fruits.clear();
System.out.println("List after clearing: " + fruits);
}
}

OUTPUT :

Fruits List: [Apple, Banana, Mango]


After adding Orange at index 1: [Apple, Orange, Banana, Mango]
Element at index 2: Banana
After removing Banana: [Apple, Orange, Mango]
Index of Mango: 2
Does the list contain Apple? true
After replacing Mango with Pineapple: [Apple, Orange, Pineapple]
Size of the list: 3
Is the list empty? false
List after clearing: []
LinkedList
LinkedList is a part of the Java Collections
Framework and is found in the java.util package. It
implements the List and Deque interfaces, providing
both list and queue operations. Unlike ArrayList, which is
based on a dynamic array, LinkedList is implemented using
a doubly linked list. This means that each element (node)
in the list contains a reference to both its previous and
next elements. This structure allows for efficient insertion
and deletion operations, particularly when dealing with
large lists.

Key Characteristics:

1. Doubly Linked List: Each element (node) contains


pointers to both the previous and next nodes. This
allows for efficient insertion and removal operations
at both ends (head and tail).

2. Slower Random Access: Unlike ArrayList, which


allows constant-time access via
index, LinkedList requires traversal from the head or
tail to reach a specific element, making random
access slower.

3. Efficient Insertions and Deletions: Adding or


removing elements from the beginning or end of the
list is efficient, as it only involves updating a few
pointers.
4. Implements Queue and Deque
Interfaces: LinkedList can be used as both a list
(like ArrayList) and a double-ended queue (deque),
meaning you can perform operations at both ends of
the list.

5. Non-Synchronized: Not thread-safe, so you need to


handle synchronization manually if used in a multi-
threaded environment.

6. Allows Duplicates : You can have multiple elements


with the same value.

Basic Syntax:

import java.util.LinkedList;

LinkedList<Type> list = new LinkedList<>();

Commonly Used Constructors:

 LinkedList(): Creates an empty linked list.

 LinkedList(Collection<? extends E> c): Creates a linked list


initialized with the elements of the given collection.

Methods in LinkedList

Below is a list of commonly used methods in LinkedList,

including methods inherited from List and Deque:


1. add(E e): Adds the specified element to the end of the
list.

2. add(int index, E element): Inserts the specified element


at the specified position in the list.

3. addAll(Collection<? extends E> c): Appends all the


elements in the specified collection to the end of the
list.

4. addFirst(E e): Inserts the specified element at the


beginning of the list.

5. addLast(E e): Appends the specified element to the end


of the list.

6. clear(): Removes all elements from the list.

7. contains(Object o): Returns true if the list contains the


specified element.

8. get(int index): Returns the element at the specified


index.

9. getFirst(): Returns the first element in the list.

10. getLast(): Returns the last element in the list.

11. remove(int index): Removes the element at the


specified index.

12. remove(Object o): Removes the first occurrence of


the specified element.
13. removeFirst(): Removes and returns the first
element of the list.

14. removeLast(): Removes and returns the last


element of the list.

15. size(): Returns the number of elements in the list.

16. isEmpty(): Returns true if the list is empty.

17. indexOf(Object o): Returns the index of the first


occurrence of the specified element.

18. lastIndexOf(Object o): Returns the index of the last


occurrence of the specified element.

19. peek(): Retrieves, but does not remove, the first


element of the list.

20. poll(): Retrieves and removes the first element of


the list, or returns null if empty.

21. offer(E e): Adds the specified element as the last


element (queue operation).

22. toArray(): Converts the LinkedList into an array of


objects.

Example Usage of LinkedList

import java.util.LinkedList;

public class LinkedListExample {


public static void main(String[] args) {
// Creating a LinkedList of String type
LinkedList<String> cities = new LinkedList<>();

// Adding elements to the LinkedList


cities.add("New York");
cities.add("London");
cities.add("Paris");
System.out.println("Cities List: " + cities);

// Adding elements at the beginning and end


cities.addFirst("Tokyo");
cities.addLast("Berlin");
System.out.println("After adding Tokyo and Berlin: " + cities);

// Accessing the first and last elements


String firstCity = cities.getFirst();
String lastCity = cities.getLast();
System.out.println("First City: " + firstCity);
System.out.println("Last City: " + lastCity);

// Removing elements from the LinkedList


cities.removeFirst(); // Removes "Tokyo"
cities.removeLast(); // Removes "Berlin"
System.out.println("After removing first and last cities: " +
cities);

// Retrieving and removing the first element (queue operation)


String polledCity = cities.poll();
System.out.println("Polled City: " + polledCity);
System.out.println("After polling: " + cities);

// Checking if the list contains an element


boolean containsLondon = cities.contains("London");
System.out.println("Does the list contain London? " +
containsLondon);

// Converting the LinkedList to an array


Object[] citiesArray = cities.toArray();
System.out.print("Cities array: ");
for (Object city : citiesArray) {
System.out.print(city + " ");
}
}
}

Output :
Cities List: [New York, London, Paris]
After adding Tokyo and Berlin: [Tokyo, New York, London, Paris, Berlin]
First City: Tokyo
Last City: Berlin
After removing first and last cities: [New York, London, Paris]
Polled City: New York
After polling: [London, Paris]
Does the list contain London? true
Cities array: London Paris

When to Use LinkedList vs ArrayList


Use LinkedList when:

 You need fast insertions and deletions at the


beginning, middle, or end of the list.

 You want to implement a queue or deque.

Use ArrayList when:

 You need fast random access to elements via index.

 You don’t expect many insertions or deletions,


especially in the middle of the list.

Vector
Vector is a legacy class in Java that is part of
the java.util package. It was introduced before the Java
Collections Framework (JCF) and has since been
retrofitted to implement the List interface. Vector is similar
to ArrayList. It is a resizable array that can grow as needed
to accommodate new elements. but with some important
differences, primarily in thread safety.

Key Characteristics:

1. Synchronized: Vector is synchronized, meaning it


is thread-safe. Multiple threads can access it
concurrently without causing issues. However, this
synchronization introduces a performance overhead,
making it slower compared to ArrayList for single-
threaded operations.

2. Dynamic Array: Like ArrayList, Vector uses a dynamic


array to store elements. It grows automatically when
it reaches its capacity.

3. Legacy Class: Even though Vector implements List,

it's considered a legacy class and is generally


replaced by ArrayList in modern applications unless
thread safety is required.

Basic Syntax:

import java.util.Vector;

Vector<Type> vector = new Vector<>();

Commonly Used Constructors:

 Vector(): Creates an empty vector with an initial


capacity of 10.
 Vector(int initialCapacity): Creates a vector with the
specified initial capacity.

 Vector(int initialCapacity, int capacityIncrement): Creates a


vector with the specified initial capacity and capacity
increment.

 Vector(Collection<? extends E> c): Creates a vector


containing the elements of the specified collection.

Methods in Vector
Below are commonly used methods of the Vector class:

1. add(E e): Adds the specified element to the end of the


vector.

2. add(int index, E element): Inserts the specified element


at the specified position.

3. addAll(Collection<? extends E> c): Adds all elements from


the specified collection to the end of the vector.

4. capacity(): Returns the current capacity of the vector.

5. clear(): Removes all elements from the vector.

6. contains(Object o): Returns true if the vector contains


the specified element.

7. elementAt(int index): Returns the element at the


specified index.
8. firstElement(): Returns the first element of the vector.

9. lastElement(): Returns the last element of the vector.

10. get(int index): Returns the element at the specified


index.

11. remove(int index): Removes the element at the


specified index.

12. remove(Object o): Removes the first occurrence of


the specified element.

13. removeAllElements(): Removes all elements from the


vector (same as clear()).

14. isEmpty(): Returns true if the vector contains no


elements.

15. size(): Returns the number of elements in the


vector.

16. trimToSize(): Trims the capacity of the vector to


the current size.

17. indexOf(Object o): Returns the index of the first


occurrence of the specified element.

18. lastIndexOf(Object o): Returns the index of the last


occurrence of the specified element.

19. toArray(): Converts the vector to an array of


objects.
20. clone(): Creates a copy of the vector.

21. set(int index, E element): Replaces the element at


the specified position with the specified element.

22. ensureCapacity(int minCapacity): Increases the


capacity of the vector if necessary to ensure it can
hold at least the specified number of elements.

Example Usage of Vector

import java.util.Vector;

public class VectorExample {


public static void main(String[] args) {
// Creating a Vector of String type
Vector<String> vector = new Vector<>();

// Adding elements to the Vector


vector.add("Apple");
vector.add("Banana");
vector.add("Cherry");
System.out.println("Vector: " + vector);

// Adding an element at a specific index


vector.add(1, "Mango");
System.out.println("After adding Mango at index 1: " + vector);

// Accessing an element at a specific index


String element = vector.get(2);
System.out.println("Element at index 2: " + element);

// Checking the first and last elements


String firstElement = vector.firstElement();
String lastElement = vector.lastElement();
System.out.println("First Element: " + firstElement);
System.out.println("Last Element: " + lastElement);

// Removing an element
vector.remove("Banana");
System.out.println("After removing Banana: " + vector);

// Checking the size and capacity of the Vector


int size = vector.size();
int capacity = vector.capacity();
System.out.println("Size of the vector: " + size);
System.out.println("Capacity of the vector: " + capacity);

// Trimming the capacity to the current size


vector.trimToSize();
System.out.println("Capacity after trim: " + vector.capacity());
}
}

Output :

Vector: [Apple, Banana, Cherry]


After adding Mango at index 1: [Apple, Mango, Banana, Cherry]
Element at index 2: Banana
First Element: Apple
Last Element: Cherry
After removing Banana: [Apple, Mango, Cherry]
Size of the vector: 3
Capacity of the vector: 10
Capacity after trim: 3

When to Use Vector vs ArrayList

Use Vector when:

 You need a thread-safe collection without explicit


synchronization.

 You require a dynamic array but need it to be


synchronized by default.

Use ArrayList when:

 You don’t need thread safety.


 You prefer a higher-performance dynamic array in
single-threaded scenarios.

HashSet
HashSet is part of the Java Collections Framework and
implements the Set interface. It is backed by a hash
table (technically a HashMap instance) and is used to store
elements in a collection that does not allow duplicates.

Key Characteristics:

1. No Duplicates: A HashSet does not allow duplicate


elements. If you attempt to add a duplicate element,
it will not be added.

2. Unordered: The elements in a HashSet are not


ordered. The order in which elements are inserted is
not maintained.

3. Null Values: HashSet allows one null value.

4. Fast Operations: The operations like adding,


removing, and checking elements happen in constant
time (O(1)), assuming there are no hash collisions.

5. Non-Synchronized: HashSet is not synchronized, so it


is not thread-safe. For thread-safe operations, you
can use Collections.synchronizedSet(new HashSet<E>()).

Basic Syntax:
import java.util.HashSet;

HashSet<Type> set = new HashSet<>();

Commonly Used Constructors:

 HashSet(): Creates an empty set with an initial capacity


of 16 and load factor of 0.75.

 HashSet(int initialCapacity): Creates an empty set with


the specified initial capacity.

 HashSet(int initialCapacity, float loadFactor): Creates a set


with the specified initial capacity and load factor.

 HashSet(Collection<? extends E> c): Creates a set


containing the elements of the specified collection.

Methods in HashSet

1. add(E e): Adds the specified element to the set if it is


not already present.

2. addAll(Collection<? extends E> c): Adds all of the elements


in the specified collection to the set.

3. clear(): Removes all elements from the set.

4. contains(Object o): Returns true if the set contains the


specified element.

5. isEmpty(): Returns true if the set contains no elements.


6. remove(Object o): Removes the specified element from
the set if it is present.

7. size(): Returns the number of elements in the set.

8. iterator(): Returns an iterator over the elements in the


set.

9. toArray(): Returns an array containing all of the


elements in the set.

10. retainAll(Collection<?> c): Retains only the elements


in the set that are contained in the specified
collection (intersection of sets).

11. removeAll(Collection<?> c): Removes from the set all


of its elements that are contained in the specified
collection.

12. clone(): Returns a shallow copy of the HashSet.

Example Usage of HashSet

import java.util.HashSet;

public class HashSetExample {


public static void main(String[] args) {
// Creating a HashSet of String type
HashSet<String> set = new HashSet<>();

// Adding elements to the HashSet


set.add("Apple");
set.add("Banana");
set.add("Cherry");
System.out.println("HashSet: " + set);

// Trying to add a duplicate element


boolean isAdded = set.add("Apple");
System.out.println("Is 'Apple' added again? " + isAdded);

// Checking if an element exists in the HashSet


boolean containsCherry = set.contains("Cherry");
System.out.println("Does the set contain 'Cherry'? " +
containsCherry);

// Removing an element from the HashSet


set.remove("Banana");
System.out.println("After removing 'Banana': " + set);

// Getting the size of the HashSet


int size = set.size();
System.out.println("Size of the HashSet: " + size);

// Iterating over the elements of the HashSet


System.out.println("Elements in the HashSet:");
for (String element : set) {
System.out.println(element);
}
}
}

Output:

HashSet: [Apple, Banana, Cherry]


Is 'Apple' added again? false
Does the set contain 'Cherry'? true
After removing 'Banana': [Apple, Cherry]
Size of the HashSet: 2
Elements in the HashSet:
Apple
Cherry

When to Use HashSet

1. No Duplicates: Use HashSet when you want to ensure


no duplicate elements are stored in the collection.

2. Fast Operations: Since HashSet is based on a hash


table, the operations are very fast with constant time
complexity (O(1)) for basic operations like add,
remove, and contains.

3. Unordered Collection: If you don’t care about the


order of elements, HashSet is a great choice.

LinkedHashSet
A LinkedHashSet in Java is a part of the Java Collections
Framework and is a combination of a HashSet and
a LinkedList. It maintains a doubly linked list running
through all of its entries, which allows it to preserve the
insertion order of elements. Like HashSet, LinkedHashSet does
not allow duplicate elements and provides constant-time
performance for basic operations such as adding,
removing, and checking for the presence of elements.

Key Characteristics:

1. No Duplicates: Like HashSet, LinkedHashSet does not


allow duplicate elements.

2. Preserves Insertion Order: Unlike HashSet, which


does not guarantee any order, LinkedHashSet maintains
the insertion order of elements.

3. Null Elements: LinkedHashSet allows a


single null element.

4. Moderate Performance: While LinkedHashSet is


slightly slower than HashSet (due to maintaining the
linked list), its performance is still fast for basic
operations like add(), remove(), and contains().

5. Non-Synchronized: LinkedHashSet is not synchronized,


so it is not thread-safe. For thread-safe operations,
you can use Collections.synchronizedSet(new

LinkedHashSet<E>()).

Basic Syntax:

import java.util.LinkedHashSet;

LinkedHashSet<Type> set = new LinkedHashSet<>();

Commonly Used Constructors:

 LinkedHashSet(): Creates an empty linked hash set with


an initial capacity of 16 and a load factor of 0.75.

 LinkedHashSet(int initialCapacity): Creates a linked hash


set with the specified initial capacity.

 LinkedHashSet(int initialCapacity, float loadFactor): Creates a


linked hash set with the specified initial capacity and
load factor.

 LinkedHashSet(Collection<? extends E> c): Creates a linked


hash set containing the elements of the specified
collection.

Methods in LinkedHashSet
Since LinkedHashSet extends HashSet, it inherits all the
methods from HashSet. Here are the most commonly used
ones:

1. add(E e): Adds the specified element to the set if it is


not already present.

2. addAll(Collection<? extends E> c): Adds all the elements


from the specified collection to this set.

3. clear(): Removes all the elements from the set.

4. contains(Object o): Returns true if the set contains the


specified element.

5. remove(Object o): Removes the specified element from


the set if it is present.

6. size(): Returns the number of elements in the set.

7. isEmpty(): Returns true if the set contains no elements.

8. iterator(): Returns an iterator over the elements in the


set.

9. toArray(): Returns an array containing all of the


elements in the set.

10. retainAll(Collection<?> c): Retains only the elements


in the set that are contained in the specified
collection.
11. removeAll(Collection<?> c): Removes from the set all
of its elements that are contained in the specified
collection.

12. clone(): Returns a shallow copy of the LinkedHashSet.

Example Usage of LinkedHashSet

import java.util.LinkedHashSet;

public class LinkedHashSetExample {


public static void main(String[] args) {
// Creating a LinkedHashSet of String type
LinkedHashSet<String> set = new LinkedHashSet<>();

// Adding elements to the LinkedHashSet


set.add("Apple");
set.add("Banana");
set.add("Cherry");
System.out.println("LinkedHashSet: " + set);

// Trying to add a duplicate element


boolean isAdded = set.add("Apple");
System.out.println("Is 'Apple' added again? " + isAdded);

// Checking if an element exists in the LinkedHashSet


boolean containsCherry = set.contains("Cherry");
System.out.println("Does the set contain 'Cherry'? " +
containsCherry);

// Removing an element from the LinkedHashSet


set.remove("Banana");
System.out.println("After removing 'Banana': " + set);

// Getting the size of the LinkedHashSet


int size = set.size();
System.out.println("Size of the LinkedHashSet: " + size);

// Iterating over the elements of the LinkedHashSet


System.out.println("Elements in the LinkedHashSet:");
for (String element : set) {
System.out.println(element);
}
}
}
Output:

LinkedHashSet: [Apple, Banana, Cherry]


Is 'Apple' added again? false
Does the set contain 'Cherry'? true
After removing 'Banana': [Apple, Cherry]
Size of the LinkedHashSet: 2
Elements in the LinkedHashSet:
Apple
Cherry

When to Use LinkedHashSet

1. Preserving Insertion Order: Use LinkedHashSet when


you need a collection that maintains the insertion
order of elements. This is useful when you need
unique elements but also care about the order in
which they are processed.

2. No Duplicates: Like all sets, LinkedHashSet ensures


that there are no duplicate elements.

3. Moderate Performance: Though it is slightly slower


than HashSet due to the linked list overhead, it still
provides constant-time performance for basic
operations.

TreeSet
TreeSet is a class in Java that implements the Set interface
and is part of the Java Collections Framework. It is
backed by a TreeMap and stores elements in a sorted
and ascending order by default.
Unlike HashSet or LinkedHashSet, TreeSet ensures that the
elements are sorted in natural order or by a specified
comparator.

Key Characteristics:

1. Sorted Order: Elements in a TreeSet are always


sorted in ascending order (natural order) or by a
comparator provided at set creation.

2. No Duplicates: Like all sets, TreeSet does not allow


duplicate elements.

3. Null Elements: TreeSet does not allow null elements,


as it uses comparisons to sort elements
and null cannot be compared.

4. Implements NavigableSet: The TreeSet class


implements the NavigableSet interface, which provides
additional methods for navigation like getting the
closest match for a given element.

5. Slower Performance: Compared


to HashSet and LinkedHashSet, TreeSet operations have a
time complexity of O(log n) due to its underlying tree
structure (typically a Red-Black tree).

6. Non-Synchronized: TreeSet is not synchronized, so it


is not thread-safe. For thread-safe operations, you
can use Collections.synchronizedSortedSet(new

TreeSet<E>()).

Basic Syntax:
import java.util.TreeSet;

TreeSet<Type> set = new TreeSet<>();

Commonly Used Constructors:

 TreeSet(): Creates an empty tree set, sorted according


to the natural ordering of its elements.

 TreeSet(Comparator<? super E> comparator): Creates an


empty tree set, sorted according to the specified
comparator.

 TreeSet(Collection<? extends E> c): Creates a tree set


containing the elements of the specified collection,
sorted according to the natural ordering of its
elements.

 TreeSet(SortedSet<E> s): Creates a tree set containing


the elements of the specified sorted set, sorted in the
same order.

Methods in TreeSet

TreeSet inherits methods from the NavigableSet, SortedSet,

and Set interfaces. Here are the most commonly used


methods:

1. add(E e): Adds the specified element to the set if it is


not already present.
2. addAll(Collection<? extends E> c): Adds all the elements
from the specified collection to the set.

3. clear(): Removes all elements from the set.

4. contains(Object o): Returns true if the set contains the


specified element.

5. remove(Object o): Removes the specified element from


the set if it is present.

6. size(): Returns the number of elements in the set.

7. isEmpty(): Returns true if the set contains no elements.

8. iterator(): Returns an iterator over the elements in the


set in ascending order.

9. toArray(): Returns an array containing all of the


elements in the set.

10. first(): Returns the first (lowest) element currently


in the set.

11. last(): Returns the last (highest) element currently


in the set.

12. higher(E e): Returns the least element in this set


strictly greater than the given element, or null if
there is no such element.
13. lower(E e): Returns the greatest element in this set
strictly less than the given element, or null if there is
no such element.

14. 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.

15. 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.

16. pollFirst(): Retrieves and removes the first (lowest)


element, or returns null if the set is empty.

17. pollLast(): Retrieves and removes the last (highest)


element, or returns null if the set is empty.

Example Usage of TreeSet

import java.util.TreeSet;

public class TreeSetExample {


public static void main(String[] args) {
// Creating a TreeSet of String type
TreeSet<String> set = new TreeSet<>();

// Adding elements to the TreeSet


set.add("Apple");
set.add("Banana");
set.add("Cherry");
System.out.println("TreeSet: " + set);

// Trying to add a duplicate element


boolean isAdded = set.add("Apple");
System.out.println("Is 'Apple' added again? " + isAdded);

// Checking if an element exists in the TreeSet


boolean containsCherry = set.contains("Cherry");
System.out.println("Does the set contain 'Cherry'? " +
containsCherry);

// Removing an element from the TreeSet


set.remove("Banana");
System.out.println("After removing 'Banana': " + set);

// Getting the size of the TreeSet


int size = set.size();
System.out.println("Size of the TreeSet: " + size);

// Getting the first and last elements


System.out.println("First element: " + set.first());
System.out.println("Last element: " + set.last());

// Getting higher and lower elements


System.out.println("Higher than 'Apple': " + set.higher("Apple"));
System.out.println("Lower than 'Cherry': " + set.lower("Cherry"));

// Iterating over the elements of the TreeSet


System.out.println("Elements in the TreeSet:");
for (String element : set) {
System.out.println(element);
}
}
}

Output:

TreeSet: [Apple, Banana, Cherry]


Is 'Apple' added again? false
Does the set contain 'Cherry'? true
After removing 'Banana': [Apple, Cherry]
Size of the TreeSet: 2
First element: Apple
Last element: Cherry
Higher than 'Apple': Cherry
Lower than 'Cherry': Apple
Elements in the TreeSet:
Apple
Cherry

When to Use TreeSet


1. Sorted Collection: Use TreeSet when you need
elements to be stored in a sorted order (either
natural or based on a comparator).

2. No Duplicates: Like other sets, TreeSet prevents


duplicate elements from being added.

3. Range Operations: If you need operations such as


finding the closest matches to an element or fetching
elements in a certain range (headSet, tailSet), TreeSet is
a good option.

4. Moderate Performance: Operations


like add(), remove(), and contains() take O(log n) time,
making it slower than HashSet, but it offers the benefit
of maintaining a sorted set.

Queue
In Java, the Queue interface, part of the Java Collections
Framework, represents a collection designed for holding
elements prior to processing. A queue follows FIFO
(First-In-First-Out) ordering, where elements are
inserted at the rear and removed from the front.

Key Characteristics:

1. FIFO Ordering: The queue typically processes


elements in the order they were added (though
variations like priority queues don’t follow FIFO).
2. No Direct Access: Unlike lists, queues do not
provide indexed access to elements. You can only
interact with the head and tail.

3. Null Values: Most queue implementations


(like PriorityQueue, ArrayDeque) do not allow null values.

4. Blocking and Non-blocking Queues:


The Queue interface has several subinterfaces
like BlockingQueue that support blocking operations for
thread-safe access.

5. Non-Synchronized: Most queue implementations


are not synchronized, so they are not thread-safe. For
thread-safe operations, you can use concurrent queue
implementations like ConcurrentLinkedQueue.

Queue Implementations:

 LinkedList: Implements Queue and Deque interfaces.


Provides a FIFO structure when used as a queue.

 PriorityQueue: A queue that orders its elements


based on their natural ordering or by a provided
comparator.

 ArrayDeque: A resizable array that


implements Queue and Deque. More efficient
than LinkedList for queues.

Commonly Used Constructors:


 For a LinkedList queue
Queue<Type> queue = new LinkedList<>();

 For a PriorityQueue queue


Queue<Type> queue = new PriorityQueue<>();

Commonly Used Methods in Queue

Here are some of the most commonly used methods in


the Queue interface:

1. add(E e): Inserts the specified element into the queue.


Throws IllegalStateException if the queue is full.

2. offer(E e): Inserts the specified element into the queue.


Returns true if successful; false if the queue is full
(more commonly used than add() because it doesn't
throw an exception).

3. remove(): Retrieves and removes the head of the


queue. Throws NoSuchElementException if the queue is
empty.

4. poll(): Retrieves and removes the head of the queue,


or returns null if the queue is empty (more commonly
used than remove() because it doesn’t throw an
exception).

5. element(): Retrieves, but does not remove, the head of


the queue. Throws NoSuchElementException if the queue is
empty.
6. peek(): Retrieves, but does not remove, the head of
the queue, or returns null if the queue is empty.

7. size(): Returns the number of elements in the queue.

8. isEmpty(): Returns true if the queue contains no


elements.

9. clear(): Removes all elements from the queue.

Example Usage of Queue

import java.util.LinkedList;
import java.util.Queue;

public class QueueExample {


public static void main(String[] args) {
// Creating a queue using LinkedList
Queue<String> queue = new LinkedList<>();

// Adding elements to the queue


queue.add("Apple");
queue.add("Banana");
queue.add("Cherry");
System.out.println("Queue: " + queue);

// Removing the head of the queue


String removedElement = queue.remove();
System.out.println("Removed: " + removedElement);
System.out.println("Queue after removal: " + queue);

// Accessing the head element without removing it


String headElement = queue.peek();
System.out.println("Head of the queue: " + headElement);

// Adding another element using offer()


queue.offer("Date");
System.out.println("Queue after adding 'Date': " + queue);

// Removing all elements


queue.clear();
System.out.println("Queue after clearing: " + queue.isEmpty());
}
}
Output:

Queue: [Apple, Banana, Cherry]


Removed: Apple
Queue after removal: [Banana, Cherry]
Head of the queue: Banana
Queue after adding 'Date': [Banana, Cherry, Date]
Queue after clearing: true

When to Use Queue

1. Processing Tasks in Order: Use Queue when you


need to process elements in the order they were
added (FIFO).

2. Priority-Based Processing: If you need elements


processed in a specific order other than FIFO (e.g.,
by priority), you can use PriorityQueue.

3. Thread Safety: Use implementations


like BlockingQueue in multi-threaded environments
where thread safety and blocking operations are
important.

ArrayDeque
The ArrayDeque class in Java is a resizable, array-based
implementation of both the Deque (Double-Ended
Queue) interface and the Queue interface. It can be used to
create a stack, a queue, or a deque depending on the
operations performed on it. It is more efficient
than LinkedList for queue and stack operations due to its
dynamic resizing nature and array-based structure.
ArrayDeque in Java is a part of the Java Collections
Framework and implements the Deque interface. It is a
resizable array-based implementation of a deque (double-
ended queue), which allows elements to be added or
removed from both ends. ArrayDeque is not synchronized,
making it not thread-safe, but it provides better
performance compared to LinkedList for most deque
operations.

Key Characteristics:

1. Resizable Array: Unlike ArrayList, the ArrayDeque does


not have a fixed size. It automatically grows as
elements are added.

2. No Null Elements: Unlike some other collections


(like LinkedList), ArrayDeque does not permit null values.

3. Efficient: It is generally faster than LinkedList for


implementing stacks and queues, as it doesn't have
the overhead of node management.

4. Deque Functionality: It can operate as both


a queue (FIFO) and a stack (LIFO) by
adding/removing elements from both ends.

5. No Capacity Restrictions: While ArrayDeque is based


on an array, it dynamically resizes, so there is no
need to worry about exceeding an initial capacity.

Commonly Used Constructors:


 ArrayDeque(): Creates an empty deque.

 ArrayDeque(int numElements): Creates a deque with an


initial capacity specified by numElements.

Key Methods in ArrayDeque

1. addFirst(E e): Inserts the element at the front of the


deque.

2. addLast(E e): Inserts the element at the rear of the


deque.

3. offerFirst(E e): Inserts the element at the front of the


deque, returning false if it cannot be added.

4. offerLast(E e): Inserts the element at the rear of the


deque, returning false if it cannot be added.

5. removeFirst(): Removes and returns the element at the


front. Throws NoSuchElementException if the deque is
empty.

6. removeLast(): Removes and returns the element at the


rear. Throws NoSuchElementException if the deque is
empty.

7. pollFirst(): Retrieves and removes the element at the


front, or returns null if the deque is empty.

8. pollLast(): Retrieves and removes the element at the


rear, or returns null if the deque is empty.
9. getFirst(): Retrieves but does not remove the element
at the front. Throws NoSuchElementException if the deque
is empty.

10. getLast(): Retrieves but does not remove the


element at the rear. Throws NoSuchElementException if
the deque is empty.

11. peekFirst(): Retrieves but does not remove the


element at the front, or returns null if the deque is
empty.

12. peekFirst(): Retrieves but does not remove the


element at the front, or returns null if the deque is
empty.

13. size(): Returns the number of elements in the


deque.

14. isEmpty(): Returns true if the deque contains no


elements.

15. clear(): Removes all elements from the deque.

16. iterator(): Returns an iterator over the elements in


the deque in proper sequence.

17. descendingIterator(): Returns an iterator over the


elements in reverse order.

Example Usage of ArrayDeque


import java.util.ArrayDeque;
import java.util.Deque;

public class ArrayDequeExample {


public static void main(String[] args) {
// Creating an ArrayDeque
Deque<String> deque = new ArrayDeque<>();

// Adding elements to the deque (acting as a stack and queue)


deque.addFirst("Element 1 (Stack)");
deque.addFirst("Element 2 (Stack)");
deque.addLast("Element 3 (Queue)");
deque.addLast("Element 4 (Queue)");

System.out.println("Deque after adding elements: " + deque);

// Removing elements from the deque


String first = deque.removeFirst(); // Acts like a stack (LIFO)
String last = deque.removeLast(); // Acts like a queue (FIFO)

System.out.println("Removed first (LIFO): " + first);


System.out.println("Removed last (FIFO): " + last);
System.out.println("Deque after removal: " + deque);

// Peeking at elements without removing them


String peekFirst = deque.peekFirst();
String peekLast = deque.peekLast();
System.out.println("Peek first element: " + peekFirst);
System.out.println("Peek last element: " + peekLast);

// Checking if the deque is empty


boolean isEmpty = deque.isEmpty();
System.out.println("Is deque empty? " + isEmpty);

// Clearing the deque


deque.clear();
System.out.println("Deque after clearing: " + deque);
}
}

Output:

Deque after adding elements: [Element 2 (Stack), Element 1 (Stack),


Element 3 (Queue), Element 4 (Queue)]
Removed first (LIFO): Element 2 (Stack)
Removed last (FIFO): Element 4 (Queue)
Deque after removal: [Element 1 (Stack), Element 3 (Queue)]
Peek first element: Element 1 (Stack)
Peek last element: Element 3 (Queue)
Is deque empty? false
Deque after clearing: []

Use Cases for ArrayDeque

 Queue Operations: When you need to implement a


queue (FIFO) with efficient insertions/removals at
both ends.

 Stack Operations: When you need a stack (LIFO)


with faster access than Stack (which is synchronized
and slower).

 Deque Operations: When you need to insert/remove


elements from both ends, such as implementing a
deque or a double-ended queue.

PriorityQueue
The PriorityQueue class in Java is a part of the Java
Collections Framework and implements
the Queue interface. Unlike a regular queue, where
elements are processed in FIFO (First-In-First-
Out) order, a PriorityQueue orders its elements
according to their natural ordering (for example,
integers from low to high) or based on
a Comparator provided at the queue's construction time.

PriorityQueue in Java is a part of the Java Collections


Framework and implements the Queue interface. It is a
resizable array-based implementation of a priority queue,
which orders its elements according to their natural
ordering or by a specified comparator. The head of the
queue is the least element with respect to the specified
ordering.

Key Characteristics:

1. Priority-Based Ordering: Elements are ordered


based on their priority. By default, a min-
heap structure is used where the smallest element is
at the head of the queue. For custom ordering, you
can provide a comparator.

2. No Null Elements: PriorityQueue does not


allow null elements.

3. Not Thread-Safe: PriorityQueue is not synchronized.


For thread-safe priority queues, consider
using PriorityBlockingQueue.

4. Dynamic Resizing: Internally, PriorityQueue is backed


by a binary heap, and it resizes dynamically as more
elements are added.

5. Iterating in Any Order: The iterator provided


by PriorityQueue does not guarantee any specific order
of iteration.

Constructors of PriorityQueue:
1. PriorityQueue(): Creates an empty priority queue with
an initial capacity of 11 and orders elements
according to their natural ordering.

2. PriorityQueue(int initialCapacity): Creates an empty


priority queue with a specified initial capacity.

3. PriorityQueue(int initialCapacity, Comparator<? super E>


comparator): Creates a priority queue with the
specified initial capacity that orders its elements
according to the specified comparator.

4. PriorityQueue(int initialCapacity, Comparator<? super E>


comparator): Creates a priority queue with the
specified initial capacity that orders its elements
according to the specified comparator.

Commonly Used Methods in PriorityQueue

Adding and Inserting Elements:

1. add(E e): Inserts the specified element into the priority


queue. Throws IllegalStateException if the queue is full.

2. offer(E e): Inserts the specified element into the


priority queue. Returns true if successful, false if the
queue is full.

3. remove(): Retrieves and removes the head of the


queue. Throws NoSuchElementException if the queue is
empty.
4. poll(): Retrieves and removes the head of the queue,
or returns null if the queue is empty.

5. peek(): Retrieves, but does not remove, the head of


the queue, or returns null if the queue is empty.

6. element(): Retrieves, but does not remove, the head of


the queue. Throws NoSuchElementException if the queue is
empty.

7. size(): Returns the number of elements in the priority


queue.

8. isEmpty(): Returns true if the priority queue contains


no elements.

9. clear(): Removes all elements from the priority queue.

10. contains(Object o): Returns true if the priority queue


contains the specified element.

11. iterator(): Returns an iterator over the elements in


this priority queue, but the iterator does not
guarantee any specific order.

Example Usage of PriorityQueue

import java.util.PriorityQueue;

public class PriorityQueueExample {


public static void main(String[] args) {
// Creating a PriorityQueue
PriorityQueue<Integer> pq = new PriorityQueue<>();
// Adding elements
pq.add(30);
pq.add(20);
pq.add(10);
pq.add(40);
System.out.println("PriorityQueue: " + pq);

// Peeking at the head element


int head = pq.peek();
System.out.println("Head of the queue: " + head);

// Removing the head element (smallest element)


int removed = pq.poll();
System.out.println("Removed: " + removed);

// Printing the queue after removal


System.out.println("PriorityQueue after removal: " + pq);

// Iterating over the queue (order is not guaranteed)


System.out.print("Iterating over the queue: ");
for (Integer element : pq) {
System.out.print(element + " ");
}
}
}

PriorityQueue in Java: Detailed Explanation


The PriorityQueue class in Java is a part of the Java
Collections Framework and implements
the Queue interface. Unlike a regular queue, where
elements are processed in FIFO (First-In-First-
Out) order, a PriorityQueue orders its elements
according to their natural ordering (for example,
integers from low to high) or based on
a Comparator provided at the queue's construction time.

Key Characteristics:
1. Priority-Based Ordering: Elements are ordered
based on their priority. By default, a min-
heap structure is used where the smallest element is
at the head of the queue. For custom ordering, you
can provide a comparator.

2. No Null Elements: PriorityQueue does not


allow null elements.

3. Not Thread-Safe: PriorityQueue is not synchronized.


For thread-safe priority queues, consider
using PriorityBlockingQueue.

4. Dynamic Resizing: Internally, PriorityQueue is backed


by a binary heap, and it resizes dynamically as more
elements are added.

5. Iterating in Any Order: The iterator provided


by PriorityQueue does not guarantee any specific order
of iteration.

Constructors of PriorityQueue:
1. PriorityQueue(): Creates an empty priority queue with
an initial capacity of 11 and orders elements
according to their natural ordering.

 java

 Copy code

 PriorityQueue<Integer> pq = new PriorityQueue<>();


1. PriorityQueue(int initialCapacity): Creates an empty
priority queue with a specified initial capacity.

 java

 Copy code

 PriorityQueue<Integer> pq = new PriorityQueue<>(20);

1. PriorityQueue(int initialCapacity, Comparator<? super E>


comparator): Creates a priority queue with the
specified initial capacity that orders its elements
according to the specified comparator.

 java

 Copy code

 PriorityQueue<Integer> pq = new

PriorityQueue<>(Comparator.reverseOrder());

1. PriorityQueue(Collection<? extends E> c): Creates a


priority queue containing the elements of the
specified collection.

 java

 Copy code

 List<Integer> list = Arrays.asList(5, 2, 1, 4);

PriorityQueue<Integer> pq = new PriorityQueue<>(list);


Commonly Used Methods in PriorityQueue

Adding and Inserting Elements:

1. add(E e): Inserts the specified element into the priority


queue. Throws IllegalStateException if the queue is full.

 java

 Copy code

 pq.add(10);

1. offer(E e): Inserts the specified element into the


priority queue. Returns true if successful, false if the
queue is full.

 java

 Copy code

 pq.offer(20);

Removing and Retrieving Elements:

1. remove(): Retrieves and removes the head of the


queue. Throws NoSuchElementException if the queue is
empty.

 java

 Copy code
 int removed = pq.remove();

1. poll(): Retrieves and removes the head of the queue,


or returns null if the queue is empty.

 java

 Copy code

 Integer polled = pq.poll();

1. peek(): Retrieves, but does not remove, the head of


the queue, or returns null if the queue is empty.

 java

 Copy code

 Integer head = pq.peek();

1. element(): Retrieves, but does not remove, the head of


the queue. Throws NoSuchElementException if the queue is
empty.

 java

 Copy code

 Integer head = pq.element();

Other Utility Methods:


1. size(): Returns the number of elements in the priority
queue.

 java

 Copy code

 int size = pq.size();

1. isEmpty(): Returns true if the priority queue contains


no elements.

 java

 Copy code

 boolean isEmpty = pq.isEmpty();

1. clear(): Removes all elements from the priority queue.

 java

 Copy code

 pq.clear();

1. contains(Object o): Returns true if the priority queue


contains the specified element.

 java
 Copy code

 boolean containsTen = pq.contains(10);

1. iterator(): Returns an iterator over the elements in this


priority queue, but the iterator does not guarantee
any specific order.

 java

 Copy code

 Iterator<Integer> iterator = pq.iterator();

Example Usage of PriorityQueue

java
Copy code
import java.util.PriorityQueue;

public class PriorityQueueExample {


public static void main(String[] args) {
// Creating a PriorityQueue
PriorityQueue<Integer> pq = new PriorityQueue<>();

// Adding elements
pq.add(30);
pq.add(20);
pq.add(10);
pq.add(40);
System.out.println("PriorityQueue: " + pq);

// Peeking at the head element


int head = pq.peek();
System.out.println("Head of the queue: " + head);

// Removing the head element (smallest element)


int removed = pq.poll();
System.out.println("Removed: " + removed);

// Printing the queue after removal


System.out.println("PriorityQueue after removal: " + pq);
// Iterating over the queue (order is not guaranteed)
System.out.print("Iterating over the queue: ");
for (Integer element : pq) {
System.out.print(element + " ");
}
}
}

Output:

PriorityQueue: [10, 20, 30, 40]


Head of the queue: 10
Removed: 10
PriorityQueue after removal: [20, 40, 30]
Iterating over the queue: 20 40 30

Use Cases for PriorityQueue:

1. Task Scheduling: In scenarios where tasks have


different priorities, you can use PriorityQueue to
process tasks with the highest priority first.

2. Dijkstra’s Shortest Path Algorithm: Used in


graph-based algorithms where nodes with lower costs
are processed first.

3. Event-Driven Simulation: When events need to be


processed based on their scheduled time or priority.

4. Job Scheduling in Operating Systems: Tasks or


processes are executed based on their priority.

HashMap
A HashMap in Java is a part of the Java Collections
Framework and implements the Map interface. It stores
key-value pairs, allowing you to retrieve a value based on
its key. HashMap provides constant-time performance for
basic operations such as adding, removing, and accessing
elements, as it uses a hash table for storing the data.

HashMap in Java is a part of the Java Collections Framework


and is used to store key-value pairs. It is implemented as a
hash table, which allows for constant-time performance for
basic operations such as adding, removing, and retrieving
elements. HashMap does not maintain any order of the
elements; it neither maintains insertion order nor sorts the
elements.

Key Characteristics:

1. Stores Key-Value Pairs: Each entry in a HashMap is a


key-value pair.

2. No Duplicates for Keys: HashMap does not allow


duplicate keys. If you insert a duplicate key, the old
value is replaced by the new value.

3. Allows Null Values: A HashMap can store one null key


and multiple null values.

4. Unordered: The elements are not stored in any


particular order. The order of elements may change
over time, especially when resizing happens.
5. Non-Synchronized: HashMap is not thread-safe. For
synchronized operations, consider
using ConcurrentHashMap or manually synchronizing
the HashMap.

6. Performance: Average time complexity for basic


operations like get and put is O(1).

Constructors of HashMap:
1. HashMap(): Creates an empty HashMap with the default
initial capacity (16) and load factor (0.75).

2. HashMap(int initialCapacity): Creates a HashMap with the


specified initial capacity.

3. HashMap(int initialCapacity, float loadFactor): Creates


a HashMap with the specified initial capacity and load
factor.

4. HashMap(Map<? extends K,? extends V> m): Creates


a HashMap with the same mappings as the specified
map.

Commonly Used Methods in HashMap

Adding and Inserting Elements:

1. put(K key, V value): Inserts the specified key-value pair


into the HashMap. If the key already exists, its old value
is replaced by the new value.
2. putAll(Map<? extends K, ? extends V> m): Copies all the
key-value mappings from the specified map to
this HashMap.

3. putIfAbsent(K key, V value): Inserts the key-value pair


only if the specified key is not already associated with
a value.

4. get(Object key): Returns the value to which the


specified key is mapped, or null if the HashMap contains
no mapping for the key.

5. getOrDefault(Object key, V defaultValue): Returns the value


to which the specified key is mapped, or the default
value if the key is not found.

6. remove(Object key): Removes the mapping for the


specified key if present.

7. remove(Object key, Object value): Removes the entry for


the specified key only if it is currently mapped to the
specified value.

8. containsKey(Object key): Returns true if


the HashMap contains a mapping for the specified key.

9. containsValue(Object value): Returns true if


the HashMap maps one or more keys to the specified
value.

10. size(): Returns the number of key-value mappings


in the HashMap.
11. isEmpty(): Returns true if the HashMap contains no
key-value mappings.

12. clear(): Removes all key-value mappings from


the HashMap.

13. keySet(): Returns a Set view of the keys contained


in this HashMap.

14. values(): Returns a Collection view of the values


contained in this HashMap.

15. entrySet(): Returns a Set view of the key-value


mappings contained in this HashMap.

Example Usage of HashMap

import java.util.HashMap;

public class HashMapExample {


public static void main(String[] args) {
// Creating a HashMap
HashMap<String, Integer> map = new HashMap<>();

// Adding elements
map.put("John", 25);
map.put("Alice", 30);
map.put("Bob", 20);
map.put("Mike", 35);

// Accessing elements
System.out.println("John's age: " + map.get("John"));

// Checking if a key exists


if (map.containsKey("Alice")) {
System.out.println("Alice is in the map.");
}

// Removing an element
map.remove("Bob");

// Iterating over the map


for (String key : map.keySet()) {
System.out.println(key + ": " + map.get(key));
}

// Using entrySet() to iterate over key-value pairs


for (HashMap.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " => " +
entry.getValue());
}
}
}

Output:

John's age: 25
Alice is in the map.
John: 25
Alice: 30
Mike: 35
John => 25
Alice => 30
Mike => 35

Use Cases for HashMap:

1. Cache Implementations: HashMap is frequently used


to store cached data for quick lookups.

2. Counting Frequencies: You can use HashMap to count


the frequency of elements in an array or list.

3. Associative Arrays: It’s often used to simulate


associative arrays or dictionaries where key-value
pairs are needed.

4. Object Mapping: Used in object serialization, where


properties of objects are stored as key-value pairs.
LinkedHashMap
A LinkedHashMap in Java is a part of the Java Collections
Framework and implements the Map interface. It
extends HashMap and maintains a doubly linked list of the
entries in the map, preserving the insertion
order or access order of elements.

LinkedHashMap in Java is a part of the Java Collections


Framework and extends HashMap. It maintains a doubly
linked list running through all of its entries, which allows it
to preserve the insertion order of elements.
Additionally, LinkedHashMap can be configured to order its
entries based on access order, where the most recently
accessed entries are moved to the end of the map.

Key Characteristics:

1. Ordered Entries: Unlike HashMap, which does not


guarantee any order, LinkedHashMap maintains the order
in which elements were inserted or accessed.

2. Faster Iteration: Since LinkedHashMap maintains a


linked list of entries, iteration over the keys, values,
or entries is faster compared to HashMap.

3. Performance: Like HashMap, LinkedHashMap offers


constant time O(1) performance for operations such
as insertion, deletion, and access, with an extra
overhead of maintaining the linked list for ordering.
4. Access Order: You can create a LinkedHashMap to
maintain access order, meaning that the last
accessed element will be moved to the end of the
order.

Constructors of LinkedHashMap:

1. LinkedHashMap(): Creates an empty LinkedHashMap with


the default initial capacity (16) and load factor (0.75).

2. LinkedHashMap(int initialCapacity): Creates


a LinkedHashMap with the specified initial capacity.

3. LinkedHashMap(int initialCapacity, float loadFactor): Creates


a LinkedHashMap with the specified initial capacity and
load factor.

4. LinkedHashMap(int initialCapacity, float loadFactor, boolean


accessOrder): Creates a LinkedHashMap with the specified
initial capacity, load factor, and ordering mode
(insertion order or access order). If accessOrder is true,

the map is ordered based on the last access.

5. LinkedHashMap(Map<? extends K,? extends V> m): Creates


a LinkedHashMap with the same mappings as the
specified map.

Commonly Used Methods in LinkedHashMap


The methods in LinkedHashMap are almost identical to those
in HashMap, but it provides additional ordering behavior.
Adding and Inserting Elements:

1. put(K key, V value): Inserts the specified key-value pair


into the LinkedHashMap. If the key already exists, its old
value is replaced by the new value. The insertion
order is maintained.

Commonly Used Methods in LinkedHashMap


The methods in LinkedHashMap are almost identical to those
in HashMap, but it provides additional ordering behavior.

Adding and Inserting Elements:

1. put(K key, V value): Inserts the specified key-value pair


into the LinkedHashMap. If the key already exists, its old
value is replaced by the new value. The insertion
order is maintained.

2. putIfAbsent(K key, V value): Inserts the key-value pair


only if the specified key is not already associated with
a value.

3. get(Object key): Returns the value to which the


specified key is mapped, or null if
the LinkedHashMap contains no mapping for the key. The
access order is updated if accessOrder is true.

4. getOrDefault(Object key, V defaultValue): Returns the value


to which the specified key is mapped, or the default
value if the key is not found.
5. remove(Object key): Removes the mapping for the
specified key if present

6. containsKey(Object key): Returns true if


the LinkedHashMap contains a mapping for the specified
key.

7. containsValue(Object value): Returns true if


the LinkedHashMap maps one or more keys to the
specified value.

8. size(): Returns the number of key-value mappings in


the LinkedHashMap.

9. isEmpty(): Returns true if the LinkedHashMap contains no


key-value mappings.

10. clear(): Removes all key-value mappings from


the LinkedHashMap.

11. keySet(): Returns a Set view of the keys contained


in this LinkedHashMap.

12. values(): Returns a Collection view of the values


contained in this LinkedHashMap.

13. entrySet(): Returns a Set view of the key-value


mappings contained in this LinkedHashMap.

Example Usage of LinkedHashMap


import java.util.LinkedHashMap;

public class LinkedHashMapExample {


public static void main(String[] args) {
// Creating a LinkedHashMap
LinkedHashMap<String, Integer> map = new LinkedHashMap<>();

// Adding elements
map.put("John", 25);
map.put("Alice", 30);
map.put("Bob", 20);
map.put("Mike", 35);

// Accessing elements
System.out.println("John's age: " + map.get("John"));

// Checking if a key exists


if (map.containsKey("Alice")) {
System.out.println("Alice is in the map.");
}

// Removing an element
map.remove("Bob");

// Iterating over the map in insertion order


for (String key : map.keySet()) {
System.out.println(key + ": " + map.get(key));
}

// Using entrySet() to iterate over key-value pairs


for (LinkedHashMap.Entry<String, Integer> entry : map.entrySet())
{
System.out.println(entry.getKey() + " => " +
entry.getValue());
}
}
}

Output :

John's age: 25
Alice is in the map.
John: 25
Alice: 30
Mike: 35
John => 25
Alice => 30
Mike => 35
Use Cases for LinkedHashMap:

1. Caches with Access Order: LinkedHashMap is useful for


building LRU (Least Recently Used) caches. By
setting accessOrder = true, you can easily implement a
cache that removes the least recently accessed entry.

2. Maintaining Insertion Order: When you need to


store mappings in the order they were inserted (e.g.,
for a user interface that displays items in the order
they were added).

3. Predictable Iteration Order: It is useful when you


need predictable iteration order for testing, logging,
or debugging.

TreeMap
A TreeMap in Java is part of the Java Collections
Framework and implements
the NavigableMap interface. It is a sorted map that
orders its elements based on their keys, either by
their natural ordering (if the keys implement Comparable)

or by a custom comparator provided at the time of map


creation.

TreeMap in Java is a part of the Java Collections Framework


and implements the NavigableMap interface, which extends
the SortedMap interface. It stores key-value pairs in a sorted
order based on the natural ordering of the keys or by a
specified comparator. TreeMap is implemented using a Red-
Black tree, which ensures that the map remains balanced
and provides log(n) time complexity for basic

Key Characteristics:

1. Sorted Order: The keys are always sorted in


ascending order by default. You can specify a custom
comparator to sort in a different order.

2. Navigable: TreeMap provides methods to navigate


through the keys
(e.g., firstKey(), lastKey(), headMap(), tailMap()).

3. Red-Black Tree: Internally, TreeMap is implemented


as a Red-Black Tree, which guarantees O(log(n))
time complexity for common operations
like put(), get(), remove(), etc.

4. No Null Keys: TreeMap does not allow null keys (it


will throw a NullPointerException), but null values are
permitted.

Constructors of TreeMap:

1. TreeMap(): Creates an empty TreeMap with natural


ordering of its keys.

2. TreeMap(Comparator<? super K> comparator): Creates an


empty TreeMap that orders its keys according to the
specified comparator.

3. TreeMap(Map<? extends K,? extends V> m): Constructs a


new TreeMap containing the same mappings as the
given map, sorted according to the keys' natural
ordering.

4. TreeMap(SortedMap<K,? extends V> m): Constructs a


new TreeMap with the same mappings as the specified
sorted map, with the same ordering.

5. put(K key, V value): Associates the specified value with


the specified key in this TreeMap. If the map previously
contained a mapping for the key, the old value is
replaced.

6. putIfAbsent(K key, V value): Associates the specified key


with the specified value only if it is not already
present in the map.

7. get(Object key): Returns the value to which the


specified key is mapped, or null if this map contains
no mapping for the key.

8. getOrDefault(Object key, V defaultValue): Returns the value


to which the specified key is mapped, or the default
value if the map contains no mapping for the key.

9. getOrDefault(Object key, V defaultValue): Returns the value


to which the specified key is mapped, or the default
value if the map contains no mapping for the key.

10. containsKey(Object key): Returns true if this map


contains a mapping for the specified key.
11. containsValue(Object value): Returns true if this map
maps one or more keys to the specified value.

12. size(): Returns the number of key-value mappings


in the TreeMap.

13. isEmpty(): Returns true if the TreeMap contains no


key-value mappings.

14. clear(): Removes all key-value mappings from


the TreeMap.

15. keySet(): Returns a Set view of the keys contained


in this map, in ascending order.

16. values(): Returns a Collection view of the values


contained in this map, in the order corresponding to
ascending key order.

17. entrySet(): Returns a Set view of the key-value


mappings contained in this map, in ascending key
order.

Navigational Methods in TreeMap

1. firstKey(): Returns the first (lowest) key currently in


this map.

2. lastKey(): Returns the last (highest) key currently in


this map.
3. headMap(K toKey): Returns a view of the portion of this
map whose keys are strictly less than toKey.

4. tailMap(K fromKey): Returns a view of the portion of this


map whose keys are greater than or equal to fromKey.

5. subMap(K fromKey, K toKey): Returns a view of the


portion of this map whose keys range
from fromKey (inclusive) to toKey (exclusive).

6. lowerKey(K key): Returns the greatest key strictly less


than the given key, or null if there is no such key.

7. higherKey(K key): Returns the least key strictly greater


than the given key, or null if there is no such key.

8. floorKey(K key): Returns the greatest key less than or


equal to the given key, or null if there is no such key.

9. ceilingKey(K key): Returns the least key greater than or


equal to the given key, or null if there is no such key.

Example Usage of TreeMap

import java.util.TreeMap;

public class TreeMapExample {


public static void main(String[] args) {
// Creating a TreeMap
TreeMap<String, Integer> map = new TreeMap<>();

// Adding elements to the TreeMap


map.put("John", 25);
map.put("Alice", 30);
map.put("Bob", 20);
map.put("Mike", 35);
// Accessing elements
System.out.println("John's age: " + map.get("John"));

// Removing an element
map.remove("Bob");

// Iterating over the TreeMap (in sorted order)


for (String key : map.keySet()) {
System.out.println(key + ": " + map.get(key));
}

// Navigating using firstKey and lastKey


System.out.println("First Key: " + map.firstKey());
System.out.println("Last Key: " + map.lastKey());
}
}

Output

John's age: 25
Alice: 30
John: 25
Mike: 35
First Key: Alice
Last Key: Mike

Custom Comparator Example

You can use a custom comparator to sort the keys in


reverse order.

import java.util.TreeMap;
import java.util.Comparator;

public class TreeMapCustomComparatorExample {


public static void main(String[] args) {
// Creating a TreeMap with a custom comparator (reverse order)
TreeMap<String, Integer> map = new
TreeMap<>(Comparator.reverseOrder());

// Adding elements
map.put("John", 25);
map.put("Alice", 30);
map.put("Bob", 20);
map.put("Mike", 35);

// Iterating over the map (in reverse order)


for (String key : map.keySet()) {
System.out.println(key + ": " + map.get(key));
}
}
}

Output:

Mike: 35
John: 25
Bob: 20
Alice: 30

Use Cases for TreeMap:

 When you need to maintain a sorted order of keys.

 If you need to efficiently retrieve elements in a sorted


manner, for instance, generating reports, rankings,
or maintaining historical data.

 When you need efficient range queries based on keys

Hashtable in Java: Detailed Explanation


A Hashtable is a part of the Java Collections
Framework and is one of the original implementations of
a Map. It stores key-value pairs in a hash table and works
on the principle of hashing. Unlike HashMap, which is non-
synchronized, Hashtable is synchronized, making it thread-
safe for concurrent access.

Hashtable in Java is a part of the Java Collections Framework


and is used to store key-value pairs. It is similar to HashMap,

but with some key differences. Hashtable is synchronized,


making it thread-safe, and it does not allow null keys or
values.

Key Characteristics:

1. Synchronized: All operations on a Hashtable are


synchronized, meaning it is thread-safe and can be
shared across multiple threads. However,
synchronization makes it relatively slower
than HashMap.

2. No Null Keys or Values:


Unlike HashMap, Hashtable does not allow null keys or
values. If you try to insert a null key or value, it will
throw a NullPointerException.

3. Legacy Class: Hashtable was part of the original


version of Java (before the introduction
of Collections framework in Java 2) and is considered
a legacy class. Though still used, ConcurrentHashMap is
often preferred for concurrent operations.

4. Thread-Safe: Since Hashtable is synchronized,


multiple threads can access it simultaneously without
causing issues, but it can lead to performance
bottlenecks due to contention for locks.

5. Unordered: The elements (key-value pairs) in


a Hashtable are not ordered in any specific manner,
unlike TreeMap, which sorts them based on keys.

Constructors

 Hashtable(): Constructs a new, empty hashtable with


a default initial capacity (11) and load factor (0.75).

 Hashtable(int initialCapacity): Constructs a new,


empty hashtable with the specified initial capacity
and default load factor (0.75).

 Hashtable(int initialCapacity, float


loadFactor): Constructs a new, empty hashtable
with the specified initial capacity and load factor.

 Hashtable(Map<? extends K, ? extends V>


t): Constructs a new hashtable with the same
mappings as the specified map.

Commonly Used Methods in Hashtable

Adding and Inserting Elements:

1. put(K key, V value): Associates the specified value with


the specified key in this Hashtable. If the map
previously contained a mapping for the key, the old
value is replaced.
2. putIfAbsent(K key, V value): Associates the specified key
with the specified value only if it is not already
present in the map.

3. get(Object key): Returns the value to which the


specified key is mapped, or null if this map contains
no mapping for the key.

4. getOrDefault(Object key, V defaultValue): Returns the value


to which the specified key is mapped, or the default
value if the map contains no mapping for the key.

5. remove(Object key): Removes the mapping for the


specified key from this Hashtable if present.

6. clear(): Removes all of the mappings from


this Hashtable.

7. containsKey(Object key): Returns true if this map


contains a mapping for the specified key.

8. containsValue(Object value): Returns true if this map


maps one or more keys to the specified value.

9. isEmpty(): Returns true if this Hashtable contains no key-


value mappings.

10. size(): Returns the number of key-value mappings


in this Hashtable.

Example Usage of Hashtable


import java.util.Hashtable;

public class HashtableExample {


public static void main(String[] args) {
// Creating a Hashtable
Hashtable<String, Integer> table = new Hashtable<>();

// Adding elements to the Hashtable


table.put("John", 25);
table.put("Alice", 30);
table.put("Bob", 20);
table.put("Mike", 35);

// Accessing elements
System.out.println("John's age: " + table.get("John"));

// Checking presence of keys and values


System.out.println("Contains key 'John'? " +
table.containsKey("John"));
System.out.println("Contains value 30? " +
table.containsValue(30));

// Removing an element
table.remove("Bob");

// Iterating over the Hashtable


for (String key : table.keySet()) {
System.out.println(key + ": " + table.get(key));
}

// Size of Hashtable
System.out.println("Size of Hashtable: " + table.size());
}
}

Output:

John's age: 25
Contains key 'John'? true
Contains value 30? true
Alice: 30
John: 25
Mike: 35
Size of Hashtable: 3

Use Cases for Hashtable:


 Hashtable is useful when you need to store key-value
pairs and ensure thread safety. However, due to the
performance impact of synchronization, it's often
recommended to use ConcurrentHashMap for more
efficient thread-safe operations.

 It can be used in legacy applications or when working


in environments that require synchronized data
structures by default.

ConcurrentHashMap

ConcurrentHashMap is part of
the java.util.concurrent package and provides a highly
efficient, thread-safe implementation of a hash-based
Map. Unlike Hashtable, which synchronizes all
methods, ConcurrentHashMap improves performance
by partitioning the map into segments and locking only
specific segments during updates, allowing multiple
threads to read and write concurrently.

ConcurrentHashMap in Java is a part of the Java Collections


Framework and is designed for concurrent access. It is a
thread-safe implementation of the Map interface that
provides better performance and scalability compared to
synchronized collections
like Hashtable or Collections.synchronizedMap.

Key Characteristics:
1. Thread-Safe: ConcurrentHashMap allows safe, concurrent
access by multiple threads without the need for
external synchronization.

2. No Null Keys or Values: Similar


to Hashtable, ConcurrentHashMap does not allow null keys
or values. It will throw a NullPointerException if an
attempt is made to add a null key or value.

3. Segmented Locking (Fine-Grained Locking):


Instead of locking the entire map
like Hashtable, ConcurrentHashMap locks portions of the
map, enabling higher throughput in multi-threaded
environments.

4. Performance: It is faster than Hashtable in multi-


threaded environments due to reduced
contention (less time spent waiting for locks). It
scales better as the number of threads increases.

5. Weakly Consistent Iterators: Iterators returned by


the keySet(), entrySet(), and values() methods do not
throw ConcurrentModificationException. However, the
iterators are weakly consistent, meaning they
reflect the state of the map at the time of their
creation and may not show subsequent modifications
during iteration.

Constructors
 ConcurrentHashMap(): Constructs a new, empty
map with a default initial table size (16).

 ConcurrentHashMap(int
initialCapacity): Constructs a new, empty map with
an initial table size based on the given initial
capacity.

 ConcurrentHashMap(int initialCapacity, float


loadFactor): Constructs a new, empty map with an
initial table size based on the given initial capacity,
and the given load factor.

 ConcurrentHashMap(int initialCapacity, float


loadFactor, int concurrencyLevel): Constructs a
new, empty map with an initial table size based on
the given initial capacity, and the given load factor
and concurrency level.

 ConcurrentHashMap(Map<? extends K, ?
extends V> m): Constructs a new map containing
the same mappings as the given map.

Commonly Used Methods in ConcurrentHashMap

Adding and Updating Elements:

1. put(K key, V value): Associates the specified value with


the specified key. If the map previously contained a
mapping for the key, the old value is replaced.
2. putIfAbsent(K key, V value): Associates the specified key
with the value only if it is not already present in the
map.

3. replace(K key, V oldValue, V newValue): Replaces the entry


for a key only if currently mapped to a specific value.

4. get(Object key): Returns the value associated with the


specified key, or null if no mapping is found.

5. getOrDefault(Object key, V defaultValue): Returns the value


associated with the specified key, or the default value
if no mapping is found.

6. remove(Object key): Removes the mapping for the


specified key.

7. clear(): Removes all the mappings from


the ConcurrentHashMap.

8. remove(Object key, Object value): Removes the entry for a


key only if currently mapped to the specified value.

Example Usage of ConcurrentHashMap

import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapExample {


public static void main(String[] args) {
// Creating a ConcurrentHashMap
ConcurrentHashMap<String, Integer> map = new
ConcurrentHashMap<>();

// Adding elements to the ConcurrentHashMap


map.put("John", 25);
map.put("Alice", 30);
map.put("Bob", 20);
map.putIfAbsent("Mike", 35);

// Accessing elements
System.out.println("John's age: " + map.get("John"));

// Using atomic operations


map.compute("Alice", (key, val) -> val != null ? val + 5 : 30);

// Checking presence of keys and values


System.out.println("Contains key 'John'? " +
map.containsKey("John"));
System.out.println("Contains value 30? " + map.containsValue(30));

// Removing an element
map.remove("Bob");

// Iterating over the ConcurrentHashMap


for (String key : map.keySet()) {
System.out.println(key + ": " + map.get(key));
}

// Size of ConcurrentHashMap
System.out.println("Size of ConcurrentHashMap: " + map.size());
}
}

Output:

John's age: 25
Contains key 'John'? true
Contains value 30? true
Alice: 35
John: 25
Mike: 35
Size of ConcurrentHashMap: 3

ConcurrentHashMap vs Hashtable vs HashMap:

 ConcurrentHashMap: Concurrent, thread-safe, and offers


better performance than Hashtable due to fine-grained
locking.
 Hashtable: Synchronized, but has performance
limitations due to locking the entire map for every
operation.

 HashMap: Non-synchronized and not thread-safe, but


offers the best performance in single-threaded
environments.

You might also like