import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Amit");
names.add("Rahul");
names.add("Priya");
System.out.println(names);
}
}Java Collections Framework Overview: Architecture, Hierarchy, and Core Interfaces
Direct Answer & Core Concept
The Java Collections Framework (JCF) is a standard set of interfaces, classes, and algorithms used to store and manipulate groups of objects.
Instead of creating your own data structures for every application, Java provides ready-to-use collections such as ArrayList, LinkedList, HashSet, TreeSet, HashMap, and PriorityQueue.
The framework also provides common interfaces such as List, Set, Queue, Deque, and Map.
Understanding the architecture of the Collections Framework is important because it helps you choose the correct data structure for a particular problem.
Detailed Explanation & Mechanics
What Is the Java Collections Framework?
The Java Collections Framework is a unified architecture for representing and manipulating collections of objects.
It provides:
Collection interfaces
Collection implementations
Map interfaces and implementations
Iterators
Algorithms
Utility methods
Sorting and searching support
Thread-safe and unmodifiable collection utilities
A simple example is:
Here:
List↓ArrayListList describes the behavior we want, while ArrayList provides the concrete implementation.
Why Do We Need Collections?
Arrays are useful when you know the required size and need simple indexed storage.
For example:
int[] numbers = new int[5];But arrays have limitations.
Their size is fixed after creation, and they do not directly provide the rich set of operations offered by collection classes.
Collections can provide features such as:
Dynamic sizing
Searching
Sorting
Duplicate handling
Queue operations
Set operations
Key-value storage
Specialized performance characteristics
For example:
List<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);The list can grow as elements are added.
Java Collections Framework Architecture
The framework is easier to understand when divided into several major parts:
Java Collections Framework
│
├── Collection
│ ├── List
│ │ ├── ArrayList
│ │ ├── LinkedList
│ │ └── Vector
│ │
│ ├── Set
│ │ ├── HashSet
│ │ ├── LinkedHashSet
│ │ └── SortedSet
│ │ └── NavigableSet
│ │ └── TreeSet
│ │
│ └── Queue
│ ├── PriorityQueue
│ └── Deque
│ ├── ArrayDeque
│ └── LinkedList
│
└── Map
├── HashMap
├── LinkedHashMap
├── SortedMap
│ └── NavigableMap
│ └── TreeMap
├── Hashtable
└── ConcurrentHashMapThis is a conceptual hierarchy. Some classes implement multiple interfaces, so the actual type relationships are not a simple tree.
The Collection Interface
Collection<E> is one of the central interfaces in the framework.
It represents a group of objects called elements.
Common operations include:
add()remove()contains()size()isEmpty()clear()Example:
Collection<String> names = new ArrayList<>();
names.add("Amit");
names.add("Rahul");
System.out.println(names.size());Output:
2The Collection interface is the parent interface for major groups such as List, Set, and Queue.
Collection vs Collections
These two names are often confused.
Collection
Collection is an interface.
Collection<String> names;It defines common collection behavior.
Collections
Collections is a utility class.
Collections.sort(names);It provides static utility methods for working with collections.
For example:
List<Integer> numbers = new ArrayList<>(List.of(30, 10, 20));
Collections.sort(numbers);
System.out.println(numbers);Output:
[10, 20, 30]Remember:
Collection → InterfaceCollections → Utility classThe List Interface
List represents an ordered collection that generally permits duplicate elements.
Elements have positions, called indexes.
Common implementations include:
List
├── ArrayList
├── LinkedList
└── VectorExample:
List<String> names = new ArrayList<>();
names.add("Amit");
names.add("Rahul");
names.add("Amit");
System.out.println(names);Output:
[Amit, Rahul, Amit]Duplicates are allowed.
ArrayList
ArrayList is one of the most commonly used collection classes.
List<String> names = new ArrayList<>();It uses a resizable-array structure internally.
Typical strengths include:
Fast indexed access
Simple API
Good general-purpose list performance
Dynamic capacity
Example:
ArrayList<String> names = new ArrayList<>();
names.add("Amit");
names.add("Rahul");
names.add("Priya");
System.out.println(names.get(1));Output:
RahulLinkedList
LinkedList implements both List and Deque.
LinkedList<String> names = new LinkedList<>();It is based on linked nodes.
It can therefore be useful when the operations you need fit its linked/deque behavior, although ArrayList is often the better default for ordinary list usage.
Example:
LinkedList<String> names = new LinkedList<>();
names.add("Amit");
names.add("Rahul");
names.addFirst("Priya");
System.out.println(names);Output:
[Priya, Amit, Rahul]The Set Interface
Set represents a collection that does not allow duplicate elements.
Example:
Set<String> names = new HashSet<>();
names.add("Amit");
names.add("Rahul");
names.add("Amit");
System.out.println(names);The duplicate "Amit" is not added a second time.
A Set is useful when uniqueness is important.
HashSet
HashSet is a hash-based implementation of Set.
Set<String> names = new HashSet<>();It is commonly used when you need fast average-case membership operations and do not require sorted order.
Example:
Set<Integer> numbers = new HashSet<>();
numbers.add(10);
numbers.add(20);
numbers.add(10);
System.out.println(numbers);The set contains only one 10.
Do not rely on HashSet iteration order.
LinkedHashSet
LinkedHashSet combines hash-based set behavior with predictable insertion-order iteration.
Set<String> names = new LinkedHashSet<>();
names.add("A");
names.add("B");
names.add("C");When iterated, the elements are encountered in insertion order.
This is useful when you need uniqueness while also preserving insertion order.
SortedSet
SortedSet is an interface for sets that maintain their elements according to an ordering.
A common implementation is:
TreeSetExample:
SortedSet<Integer> numbers = new TreeSet<>();
numbers.add(30);
numbers.add(10);
numbers.add(20);
System.out.println(numbers);Output:
[10, 20, 30]TreeSet
TreeSet is a sorted set implementation based on a tree structure.
Example:
TreeSet<String> names = new TreeSet<>();
names.add("Rahul");
names.add("Amit");
names.add("Priya");
System.out.println(names);Output:
[Amit, Priya, Rahul]Unlike HashSet, the set maintains an ordering.
The Queue Interface
A Queue represents a collection designed for holding elements before processing.
A common queue model is:
FIFOFirst In, First OutFor example:
First → Second → Third↓First processed firstJava provides several queue implementations.
Example:
Queue<String> queue = new LinkedList<>();
queue.offer("A");
queue.offer("B");
queue.offer("C");
System.out.println(queue.poll());Output:
APriorityQueue
PriorityQueue processes elements according to its priority ordering rather than simple insertion order.
Example:
PriorityQueue<Integer> numbers = new PriorityQueue<>();
numbers.offer(30);
numbers.offer(10);
numbers.offer(20);
System.out.println(numbers.poll());Output:
10The smallest element is at the head under the natural ordering shown here.
The exact iteration order of a PriorityQueue should not be confused with repeatedly polling elements in priority order.
The Deque Interface
Deque means double-ended queue.
It allows insertion and removal at both ends.
Front ↕[A][B][C] ↕ BackExample:
Deque<String> deque = new ArrayDeque<>();
deque.addFirst("A");
deque.addLast("B");
System.out.println(deque);A deque can be used as:
Queue
Stack
Double-ended queue
ArrayDeque
ArrayDeque is a resizable-array implementation of Deque.
Example:
Deque<Integer> numbers = new ArrayDeque<>();
numbers.addLast(10);
numbers.addLast(20);
numbers.addFirst(5);
System.out.println(numbers);Output:
[5, 10, 20]For many stack or queue use cases, ArrayDeque is a strong general-purpose choice.
Stack and Deque
Older Java code may use the Stack class:
Stack<Integer> stack = new Stack<>();Modern code often uses Deque with ArrayDeque for stack behavior:
Deque<Integer> stack = new ArrayDeque<>();
stack.push(10);
stack.push(20);
System.out.println(stack.pop());Output:
20This gives LIFO behavior:
Last In → First OutThe Map Interface
Map is different from Collection.
A map stores key-value pairs.
For example:
101 → Amit102 → Rahul103 → PriyaThe key identifies the value.
Example:
Map<Integer, String> users = new HashMap<>();
users.put(101, "Amit");
users.put(102, "Rahul");
System.out.println(users.get(101));Output:
AmitImportant: Map Is Not a Collection
The Map interface does not extend Collection.
Conceptually:
Collection
├── List
├── Set
└── Queue
Map
├── HashMap
├── LinkedHashMap
└── TreeMapBoth are part of the Java Collections Framework, but they model different kinds of data.
HashMap
HashMap is one of the most commonly used map implementations.
Map<String, Integer> scores = new HashMap<>();
scores.put("Amit", 90);
scores.put("Rahul", 85);
System.out.println(scores.get("Amit"));Output:
90HashMap is generally used when you need key-based lookup without requiring sorted or insertion order.
LinkedHashMap
LinkedHashMap maintains a predictable iteration order, normally insertion order unless configured differently.
Example:
Map<Integer, String> users = new LinkedHashMap<>();
users.put(1, "Amit");
users.put(2, "Rahul");
users.put(3, "Priya");When iterated, entries are encountered in insertion order.
SortedMap
SortedMap represents a map whose keys are maintained according to an ordering.
A common implementation is:
TreeMapExample:
SortedMap<Integer, String> users = new TreeMap<>();
users.put(30, "C");
users.put(10, "A");
users.put(20, "B");
System.out.println(users);Output:
{
10=A, 20=B, 30=C
}TreeMap
TreeMap stores map entries ordered by key.
Example:
TreeMap<String, Integer> scores = new TreeMap<>();
scores.put("Rahul", 80);
scores.put("Amit", 90);
scores.put("Priya", 85);
System.out.println(scores);The keys are maintained according to their ordering.
NavigableSet
NavigableSet extends SortedSet and provides navigation operations around an ordered set.
For example:
NavigableSet<Integer> numbers = new TreeSet<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.add(40);You can ask for nearby values:
System.out.println(numbers.lower(25));
System.out.println(numbers.higher(25));Output:
2030This is useful when applications need range and neighbor queries.
NavigableMap
NavigableMap extends SortedMap and provides navigation operations for ordered keys.
Example:
NavigableMap<Integer, String> map = new TreeMap<>();
map.put(10, "A");
map.put(20, "B");
map.put(30, "C");
System.out.println(map.lowerKey(25));
System.out.println(map.higherKey(25));Output:
2030Iterator
An Iterator provides a standard way to traverse collection elements.
Example:
List<String> names = new ArrayList<>(List.of("Amit", "Rahul", "Priya"));
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}The iterator provides methods such as:
hasNext()next()remove()where supported by the iterator.
Enhanced for Loop
Most collections can also be traversed using the enhanced for loop.
List<String> names = new ArrayList<>(List.of("Amit", "Rahul", "Priya"));
for (String name : names) {
System.out.println(name);
}This is often simpler than explicitly creating an iterator.
Iterable Interface
The Iterable interface allows an object to be used with the enhanced for loop.
Collections generally implement Iterable.
Conceptually:
Iterable↓Collection↓List / Set / QueueThis is why you can write:
for (String name : names) {
System.out.println(name);
}Comparable and Comparator
The Collections Framework also works closely with Java's ordering mechanisms.
Comparable
A class can implement Comparable<T> to define its natural ordering.
class Student implements Comparable<Student> {
int age;
Student(int age) {
this.age = age;
} @Override public int compareTo(Student other) {
return Integer.compare(this.age, other.age);
}
}Comparator
A Comparator<T> provides an external ordering strategy.
Comparator<Student> byAge = Comparator.comparingInt(student -> student.age);This allows the same class to be sorted in different ways.
Collections Utility Algorithms
The Collections class provides useful operations.
For example:
List<Integer> numbers = new ArrayList<>(List.of(30, 10, 20));
Collections.sort(numbers);
System.out.println(numbers);Other useful methods include:
sort()reverse()shuffle()min()max()binarySearch()frequency()These utilities work with many collection types.
Collection Interfaces vs Implementations
A useful design principle is to program against interfaces.
Instead of:
ArrayList<String> names = new ArrayList<>();prefer:
List<String> names = new ArrayList<>();Why?
Because the variable describes what behavior the application needs rather than unnecessarily exposing the concrete implementation.
You can later change:
List<String> names = new LinkedList<>();without changing code that only requires List operations.
Choosing a Collection
The correct collection depends on the problem.
| Requirement | Common Choice |
|---|---|
| General-purpose list | ArrayList |
| Unique elements | HashSet |
| Unique + insertion order | LinkedHashSet |
| Sorted unique elements | TreeSet |
| Key-value lookup | HashMap |
| Key-value + insertion order | LinkedHashMap |
| Sorted keys | TreeMap |
| Priority processing | PriorityQueue |
| Queue/deque operations | ArrayDeque |
| Stack behavior | ArrayDeque |
| Thread-safe concurrent map | ConcurrentHashMap |
These are starting points, not universal rules. The actual choice should depend on access patterns, ordering requirements, concurrency, memory usage, and performance needs.
Array vs Collection
Arrays and collections solve related but different problems.
Array
int[] numbers = new int[5];Advantages:
Fixed-size structure
Can store primitives directly
Simple and compact
Fast indexed access
Collection
List<Integer> numbers = new ArrayList<>();Advantages:
Dynamic size
Rich APIs
Works naturally with generics
Many specialized implementations
Generics and Collections
Generics allow collections to specify the type of their elements.
Without generics:
List numbers = new ArrayList();With generics:
List<Integer> numbers = new ArrayList<>();The generic version provides better compile-time type checking.
For example:
numbers.add(10);
numbers.add(20);But this would be rejected:
numbers.add("Hello");because the list is declared as:
List<Integer>Why Generics Are Important
Generics reduce the need for manual casts.
Without a generic type, retrieving an element may require casting.
With:
List<String> names = new ArrayList<>();you can write:
String name = names.get(0);The compiler already knows that the list contains String elements.
Null Values in Collections
Many collection implementations allow null, but the rules vary by collection and operation.
For example, ArrayList can contain null:
List<String> names = new ArrayList<>();
names.add(null);But null behavior is not universal across all collection implementations.
When designing code, check the contract of the specific collection implementation you are using.
Duplicate Elements
Different collections treat duplicates differently.
List
Duplicates are allowed:
List<Integer> numbers = new ArrayList<>(List.of(10, 10, 20));Set
Duplicates are not retained:
Set<Integer> numbers = new HashSet<>();
numbers.add(10);
numbers.add(10);
numbers.add(20);The set contains only one 10.
Ordering in Collections
Ordering is another major difference.
ArrayList
Maintains list order.
LinkedHashSet
Maintains insertion-order iteration.
HashSet
Does not guarantee a predictable iteration order.
TreeSet
Maintains sorted order.
HashMap
Does not guarantee a predictable iteration order.
LinkedHashMap
Maintains predictable insertion-order iteration by default.
TreeMap
Maintains keys according to their ordering.
Understanding ordering requirements is important when choosing a collection.
Fail-Fast Iterators
Some collection iterators detect certain structural modifications made outside the iterator while iteration is in progress.
For example:
List<String> names = new ArrayList<>(List.of("A", "B", "C"));
for (String name : names) {
if (name.equals("B")) {
names.remove(name);
}
}This can result in a ConcurrentModificationException.
A safer approach for supported collections is to use an iterator's remove() method:
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
String name = iterator.next();
if (name.equals("B")) {
iterator.remove();
}
}The exact behavior depends on the collection and iterator contract.
Unmodifiable Collections
Modern Java provides convenient factory methods for creating unmodifiable collections.
For example:
List<String> names = List.of("Amit", "Rahul", "Priya");Attempting to modify the list:
names.add("John");throws an UnsupportedOperationException.
Similarly:
Set<Integer> numbers = Set.of(10, 20, 30);
Map<Integer, String> users = Map.of( 1, "Amit", 2, "Rahul");These factory-created collections are useful when you want collection contents that cannot be modified through that collection reference.
Synchronized and Concurrent Collections
Java also provides collections and wrappers designed for multithreaded applications.
Examples include:
Collections.synchronizedList()Collections.synchronizedMap()ConcurrentHashMapCopyOnWriteArrayListBlockingQueue implementationsFor example:
Map<String, Integer> map = new ConcurrentHashMap<>();The correct choice depends on the concurrency requirements.
Simply making a collection synchronized does not automatically make an entire multi-step operation atomic.
Legacy Collection Classes
Java also contains older collection classes such as:
VectorStackHashtableThey remain part of Java, but newer code often uses alternatives depending on the requirement.
For example, for stack behavior:
Deque<Integer> stack = new ArrayDeque<>();instead of:
Stack<Integer> stack = new Stack<>();For concurrent map use cases, ConcurrentHashMap is often more appropriate than the legacy Hashtable.
Core Collections Hierarchy
A simplified hierarchy to remember is:
Iterable | Collection / | \ / | \ List Set Queue | | | ArrayList HashSet PriorityQueue LinkedList LinkedHashSet Vector SortedSet | NavigableSet | TreeSet Map / | \ HashMap SortedMap | | LinkedHashMap NavigableMap | TreeMapRemember that this is a simplified conceptual view. Some implementations implement multiple interfaces.
For example:
LinkedList → List + DequeCollection Framework vs Data Structures
The Collections Framework provides implementations of common data-structure concepts.
For example:
ArrayList → Resizable-array listLinkedList → Linked-node list/dequeHashSet → Hash-based setTreeSet → Sorted tree-based setHashMap → Hash-based mapTreeMap → Sorted tree-based mapPriorityQueue → Priority queueArrayDeque → Array-backed dequeThe framework saves developers from implementing these structures from scratch.
A Simple Collections Example
import java.util.*;
public class Main {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Amit");
names.add("Rahul");
Set<String> uniqueNames = new HashSet<>(names);
Queue<String> queue = new ArrayDeque<>();
queue.offer("First");
queue.offer("Second");
Map<Integer, String> users = new HashMap<>();
users.put(1, "Amit");
users.put(2, "Rahul");
System.out.println(names);
System.out.println(uniqueNames);
System.out.println(queue);
System.out.println(users);
}
}This example demonstrates four major collection categories:
ListSetQueueMapCommon Mistakes
Mistake 1: Confusing Collection and Collections
Remember:
Collection → InterfaceCollections → Utility classMistake 2: Assuming Every Collection Allows Duplicates
List normally allows duplicates.
Set does not retain duplicate elements.
Mistake 3: Assuming HashSet Is Sorted
HashSet does not provide sorted ordering.
Use TreeSet when sorted set behavior is required.
Mistake 4: Assuming HashMap Is Ordered
Do not rely on iteration order for HashMap.
If insertion-order iteration is required, consider LinkedHashMap.
If sorted keys are required, consider TreeMap.
Mistake 5: Using Map Like a Collection
Map stores key-value associations and is separate from the Collection hierarchy.
Mistake 6: Always Choosing LinkedList
LinkedList is not automatically faster than ArrayList.
Choose based on the operations and access patterns your application actually needs.
Mistake 7: Using Concrete Types Everywhere
Prefer:
List<String> names = new ArrayList<>();over unnecessarily exposing:
ArrayList<String> names = new ArrayList<>();when the application only needs List behavior.
Best Practices
Program to Interfaces
Prefer:
List<String> names = new ArrayList<>();rather than tying the variable unnecessarily to the implementation.
Choose Based on Requirements
Ask:
Do I need duplicates?
Do I need ordering?
Do I need sorting?
Do I need key-value lookup?
Do I need queue behavior?
Do I need concurrent access?
Use Generics
Prefer:
List<Integer>over raw:
ListUnderstand Ordering
Know whether the collection guarantees insertion order, sorted order, or no predictable iteration order.
Consider Concurrency
For multithreaded applications, select a collection designed for the required concurrency behavior rather than assuming a normal collection is thread-safe.
Frequently Asked Questions
What is the Java Collections Framework?
It is a unified set of interfaces, implementations, algorithms, and utilities for storing and manipulating groups of objects.
What are the main Collection interfaces?
The major interfaces include Collection, List, Set, Queue, and Deque.
Map is also a major part of the Collections Framework, although it does not extend Collection.
What is the difference between List and Set?
A List is ordered and generally permits duplicates. A Set does not retain duplicate elements.
What is the difference between Collection and Collections?
Collection is an interface. Collections is a utility class containing static methods for working with collections.
What is the difference between ArrayList and LinkedList?
ArrayList is based on a resizable array and is commonly useful for indexed access. LinkedList is a linked-node implementation that also supports deque operations.
What is the difference between HashSet and TreeSet?
HashSet is hash-based and does not guarantee sorted order. TreeSet maintains elements according to an ordering.
What is the difference between HashMap and TreeMap?
HashMap is hash-based and does not guarantee a sorted key order. TreeMap maintains its keys according to an ordering.
Is Map part of the Collections Framework?
Yes. Map is part of the Java Collections Framework, but it does not extend the Collection interface.
Which collection should I use for unique values?
A Set is generally appropriate. Choose among implementations based on ordering and performance requirements.
Which collection is commonly used for a stack?
A Deque, commonly implemented with ArrayDeque, is often a good choice for stack behavior.
Which collection is commonly used for a queue?
Queue implementations such as ArrayDeque or PriorityQueue can be used depending on whether FIFO or priority behavior is required.
Can collections store primitive types?
Java generics use reference types, so collections normally use wrapper classes such as Integer rather than primitive types such as int.
List<Integer> numbers = new ArrayList<>();Autoboxing and unboxing make primitive values convenient to use with such collections.
Quick Revision
The Java Collections Framework can be remembered through four major categories:
Collection
│
├── List
│ ├── ArrayList
│ └── LinkedList
│
├── Set
│ ├── HashSet
│ ├── LinkedHashSet
│ └── TreeSet
│
└── Queue
├── PriorityQueue
└── Deque
└── ArrayDeque
Map
├── HashMap
├── LinkedHashMap
└── TreeMapQuick selection guide
Need ordered elements + duplicates?↓ListNeed unique elements?↓SetNeed FIFO/priority processing?↓QueueNeed both-end operations?↓DequeNeed key → value mapping?↓MapThe most important design principle is:
Choose the collection based on the behavior your application needs, and prefer programming against interfaces such as
List,Set,Queue, andMaprather than unnecessarily coupling code to a specific implementation.Graphics and Design Ideas
Graphic 1: Java Collections Framework Hierarchy
Create a large hierarchy diagram:
Architecture DiagramIterable │ Collection ┌───────┼────────┐ ↓ ↓ ↓ List Set Queue │ │ │ ArrayList HashSet PriorityQueue LinkedList LinkedHashSet Vector TreeSet │ Deque │ ArrayDeque Map ┌─────┼──────┐ ↓ ↓ ↓ HashMap LinkedHashMap TreeMapUse separate visual sections for Collection and Map.
Graphic 2: List vs Set vs Map
Create three cards:
Main.javaLISTOrderedDuplicates allowedIndex basedSETUnique elementsNo duplicatesMAPKey → ValueLookup by keyThis would be an excellent beginner-focused graphic.
Graphic 3: Choosing the Right Collection
Create a decision flow:
Architecture DiagramNeed to store data? ↓ ┌─────┼─────┬─────┐ ↓ ↓ ↓ ↓ List Set Queue Map ↓ ↓ ↓ ↓ Order Unique Process Key→ValueGraphic 4: Hash vs Linked vs Tree
Show the three major implementation styles:
Main.javaHash↓Fast lookupNo guaranteed sorted orderLinked↓Predictable insertion orderTree↓Sorted orderingGraphic 5: Interface vs Implementation
Show:
Architecture DiagramProgramming to Interface List<String> │ ↓ ArrayList<String>Then:
Architecture DiagramChange implementation List<String> │ ├── ArrayList ├── LinkedList └── Other List implementationThis visually reinforces an important Java design principle.
Graphic 6: Collection vs Collections
A small comparison card:
Main.javaCollection↓InterfaceCollections↓Utility class↓sort()reverse()shuffle()min()max()This helps beginners remember one of the most common Java terminology confusions.
Runnable Code Example: Java Collections Framework Overview
Java 17+import java.util.List;
import java.util.Set;
import java.util.Map;
public class CollectionsOverviewDemo {
public static void main(String[] args) {
List<String> list = List.of("A", "B", "C");
// Immutable list (Java 9+)
Set<String> set = Set.of("Apple", "Banana");
// Unique set
Map<String, Integer> map = Map.of("Key1", 100, "Key2", 200);
System.out.println("List: " + list + ", Set: " + set + ", Map: " + map);
}
}