12. Collections


Part 1: Collection Types Overview

What are Collections?

Definition: Data structures that store and manage groups of objects

Why Use Collections?

  • Store multiple values efficiently

  • Dynamic sizing (grow/shrink as needed)

  • Rich functionality (search, sort, filter)

  • Type-safe with generics

Categories:

  • Lists - Ordered, indexed access (Array, List<T>, ArrayList)

  • Dictionaries - Key-value pairs (Dictionary, SortedDictionary, Hashtable)

  • Sets - Unique elements (HashSet, SortedSet)

  • Queues/Stacks - Specialized ordering (Queue, Stack)

  • Linked - Node-based traversal (LinkedList)

  • Bit Collections - Boolean flags (BitArray)


Part 2: Arrays & Lists

1. Array

Type: Fixed-size, indexed, immutable length

When to Use:

  • Know exact size in advance

  • Performance critical (fastest access)

  • Multi-dimensional data

Namespace: System

Creation

Access

Add/Remove

Key Properties & Methods


2. List<T>

Type: Dynamic array, indexed, mutable, generic

When to Use:

  • Unknown size (default choice for collections)

  • Need indexed access

  • Frequent additions/removals

Namespace: System.Collections.Generic

Creation

Access

Add/Remove

Key Properties & Methods

Performance Notes

  • Capacity doubling: When full, capacity doubles (expensive)

  • Pre-allocate: Use new List<int>(expectedSize) if size known

  • Insertion: O(n) for Insert, O(1) for Add (at end)

  • Access: O(1) by index


3. ArrayList (Legacy)

Type: Dynamic array, indexed, mutable, non-generic (stores objects)

When to Use:Don't use in new code - use `List instead

Why Avoid:

  • No type safety

  • Boxing/unboxing overhead for value types

  • Slower than generic collections

Namespace: System.Collections

Creation

Access

Add/Remove

Key Properties & Methods

Migration Example


Part 3: Dictionaries (Key-Value Collections)

4. Dictionary<TKey, TValue>

Type: Key-value pairs, unordered, unique keys, fast lookups (hash table)

When to Use:

  • Need fast lookup by key (O(1))

  • Keys must be unique

  • Order doesn't matter

Namespace: System.Collections.Generic

Creation

Access

Add/Remove

Key Properties & Methods

Performance

  • Lookup: O(1) average, O(n) worst case

  • Insert: O(1) average

  • Remove: O(1) average

  • Best for: Fast lookups by key


5. SortedDictionary<TKey, TValue>

Type: Key-value pairs, sorted by key, slower than Dictionary

When to Use:

  • Need keys in sorted order

  • Willing to sacrifice speed for ordering

Namespace: System.Collections.Generic

Creation

Access

Add/Remove

Key Properties & Methods

Performance

  • Lookup: O(log n)

  • Insert: O(log n)

  • Remove: O(log n)

  • Ordered iteration: Yes (by key)

Dictionary vs SortedDictionary

Feature
Dictionary
SortedDictionary

Order

Unordered

Sorted by key

Lookup

O(1)

O(log n)

Insert

O(1)

O(log n)

Use when

Speed critical

Order matters


6. SortedList<TKey, TValue>

Type: Key-value pairs, sorted by key, indexed access

When to Use:

  • Need both key-value lookup AND indexed access

  • Small collections (< 1000 items)

  • Memory efficient

Namespace: System.Collections.Generic

Creation

Access

Add/Remove

Key Properties & Methods

SortedList vs SortedDictionary

Feature
SortedList
SortedDictionary

Memory

Less

More

Indexed access

Yes

No

Insert/Remove

O(n)

O(log n)

Lookup

O(log n)

O(log n)

Best for

Small, memory-critical

Large, frequent updates


7. Hashtable (Legacy)

Type: Key-value pairs, non-generic, stores objects, legacy

When to Use:Don't use in new code - use Dictionary<TKey, TValue> instead

Namespace: System.Collections

Creation

Access

Add/Remove

Key Properties & Methods


Part 4: Sets (Unique Elements)

8. HashSet<T>

Type: Unordered, unique elements, no indexing, fast lookups

When to Use:

  • Need unique elements only

  • Fast membership tests (O(1))

  • Set operations (union, intersection, etc.)

Namespace: System.Collections.Generic

Creation

Access

Add/Remove

Set Operations

Key Properties & Methods


9. SortedSet<T>

Type: Sorted order, unique elements, no indexing

When to Use:

  • Need unique elements in sorted order

  • Need Min/Max quickly

Namespace: System.Collections.Generic

Creation

Access

Add/Remove

Set Operations

Unique Features

HashSet vs SortedSet

Feature
HashSet
SortedSet

Order

Unordered

Sorted

Lookup

O(1)

O(log n)

Insert

O(1)

O(log n)

Min/Max

O(n)

O(1)

Use when

Speed only

Need ordering


Part 5: Queues & Stacks

10. Stack<T>

Type: LIFO (Last In, First Out), no indexing

When to Use:

  • Undo/redo functionality

  • Recursive algorithms (call stack)

  • Depth-first traversal

  • Expression evaluation

Namespace: System.Collections.Generic

Creation

Operations

Key Properties & Methods

Safe Access


11. Queue<T>

Type: FIFO (First In, First Out), no indexing

When to Use:

  • Process items in order received

  • Breadth-first traversal

  • Message queues

  • Print spooling

Namespace: System.Collections.Generic

Creation

Operations

Key Properties & Methods

Safe Access


Part 6: Specialized Collections

12. LinkedList<T>

Type: Doubly-linked list, no indexing, efficient insertion/removal

When to Use:

  • Frequent insertions/removals in middle

  • Don't need indexed access

  • Implement custom data structures (deque, etc.)

Namespace: System.Collections.Generic

Creation

Node-Based Operations

Key Properties & Methods

Performance

  • Access by index: ❌ Not supported (O(n) traversal)

  • Insert/Remove at known position: O(1)

  • Insert/Remove at unknown position: O(n) to find + O(1) to modify

  • Best for: Frequent mid-list insertions/removals


13. BitArray

Type: Array of boolean values stored as bits, mutable

When to Use:

  • Store boolean flags efficiently (8x memory saving)

  • Bitwise operations on large boolean sets

  • Bit manipulation

Namespace: System.Collections

Creation

Access

Modify

Bitwise Operations

Key Properties & Methods


Part 7: Concurrent Collections (Thread-Safe)

Namespace: System.Collections.Concurrent

When to Use: Multi-threaded scenarios

Thread-Safe Collections


Part 8: Collection Comparison Tables

Quick Comparison Table

Collection
Ordered
Unique
Indexed
Add/Remove
Time Complexity
Use Case

Array

Yes

No

Yes

❌ Fixed

O(1) access

Fixed-size data

List<T>

Yes

No

Yes

Add, Remove

O(1) access, O(n) insert

Dynamic arrays

ArrayList

Yes

No

Yes

Add, Remove

Same as List

❌ Legacy (avoid)

Dictionary

No

Keys

By key

Add, Remove

O(1) lookup

Fast key-value

SortedDictionary

Sorted

Keys

By key

Add, Remove

O(log n)

Sorted key-value

SortedList

Sorted

Keys

Yes

Add, Remove

O(log n) lookup

Small sorted + indexed

Hashtable

No

Keys

By key

Add, Remove

O(1) lookup

❌ Legacy (avoid)

HashSet<T>

No

Yes

No

Add, Remove

O(1) lookup

Unique items

SortedSet<T>

Sorted

Yes

No

Add, Remove

O(log n)

Unique + sorted

Stack<T>

LIFO

No

No

Push, Pop

O(1)

LIFO operations

Queue<T>

FIFO

No

No

Enqueue, Dequeue

O(1)

FIFO operations

LinkedList<T>

Yes

No

No

AddFirst/Last

O(1) at known node

Frequent mid-insert

BitArray

Yes

No

Yes

❌ Fixed

O(1) access

Boolean flags

Performance Comparison

Operation
Array
List<T>
Dictionary
HashSet
LinkedList

Access by index

O(1)

O(1)

N/A

N/A

O(n)

Access by key

N/A

N/A

O(1)

N/A

N/A

Insert at end

O(1)*

O(1)

O(1)

O(1)

Insert at start

O(n)

N/A

N/A

O(1)

Insert in middle

O(n)

N/A

N/A

O(1)**

Remove

O(n)

O(1)

O(1)

O(1)**

Search

O(n)

O(n)

O(1)

O(1)

O(n)

Memory

Low

Low

Medium

Medium

High

  • Amortized (may resize) ** If node is already known


Part 9: Special Properties Explained

Which Collections Have Special Properties?

Legacy/Non-Generic Collections ONLY:

  • Array - Has Rank, IsFixedSize, IsReadOnly, IsSynchronized, SyncRoot

  • ArrayList - Has IsFixedSize, IsReadOnly, IsSynchronized, SyncRoot

  • Hashtable - Has IsFixedSize, IsReadOnly, IsSynchronized, SyncRoot

  • BitArray - Has IsSynchronized, SyncRoot

  • Queue (non-generic) - Has IsSynchronized, SyncRoot

  • Stack (non-generic) - Has IsSynchronized, SyncRoot

Modern/Generic Collections DO NOT Have These:

  • List<T>, Dictionary<TKey,TValue>, HashSet<T>, SortedSet<T>, Queue<T>, Stack<T>, LinkedList<T>

  • None of these have special properties

Why the Difference?

Legacy Collections (pre-.NET 2.0):

  • Built when multithreading was handled differently

  • Implement ICollection interface (non-generic) which requires:

    • IsSynchronized - Is collection thread-safe?

    • SyncRoot - Object to lock on for thread safety

    • IsFixedSize - Can size change?

    • IsReadOnly - Can items be modified?

Modern Generic Collections (.NET 2.0+):

  • Built with better design principles

  • Thread safety handled externally (use Concurrent* collections)

  • Don't clutter API with rarely-used properties

  • Simpler, cleaner interfaces

Property Meanings

Rank (Array only)

IsFixedSize

  • true = Cannot add/remove elements (Array)

  • false = Can grow/shrink (ArrayList, Hashtable)

IsReadOnly

  • true = Cannot modify elements

  • Usually false for standard collections

IsSynchronized

  • true = Thread-safe (rarely true by default)

  • false = NOT thread-safe (most collections)

  • ❌ Legacy property - use Concurrent* collections instead

SyncRoot

  • Object to use with lock() for thread safety

  • ❌ Legacy pattern - use Concurrent* collections instead

Quick Rule

  • Using generics (`)? No special properties.

  • Using old non-generic? Has special properties.

  • Need thread safety? Use System.Collections.Concurrent


Part 10: Best Practices & Guidelines

Choosing the Right Collection

Decision Tree:

General Guidelines

Do:

  • Use generic collections (List<T>, not ArrayList`)

  • Use Dictionary<K,V> for fast lookups

  • Use `HashSet for unique elements

  • Pre-allocate size if known: new List<int>(1000)

  • Use Concurrent* collections for thread safety

  • Use collection expressions (C# 12.0+): List<int> list = [1, 2, 3];

Don't:

  • Use non-generic collections (ArrayList, Hashtable) in new code

  • Use Add() in loops without pre-allocating capacity

  • Box value types (use generics)

  • Use lock(collection) for thread safety (use Concurrent*)

  • Access List/Array by index in tight loops (use foreach if possible)

Performance Tips

List<T> Capacity:

Dictionary vs List for Lookups:

Avoid Boxing:


Quick Reference Summary

Most Common Collections

For general use:

  • `List - Dynamic array (default choice)

  • Dictionary<K,V> - Fast key-value lookup

  • `HashSet - Unique elements

For specialized needs:

  • SortedDictionary<K,V> - Sorted key-value

  • `SortedSet - Sorted unique elements

  • Queue<T> - FIFO operations

  • `Stack**** - LIFO operations

  • `LinkedList - Frequent insertions/removals

For thread safety:

  • ConcurrentDictionary<K,V>

  • `ConcurrentQueue

  • `ConcurrentStack

  • `ConcurrentBag

  • `BlockingCollection

Key Terminology

  • Immutable Length - Size cannot change (Array)

  • Mutable - Can add/remove elements

  • Generic - Type-safe (List<T>, Dictionary<K,V>`)

  • Non-Generic - Stores objects, requires casting (ArrayList, Hashtable) - ❌ Avoid

  • LIFO - Last In, First Out (Stack)

  • FIFO - First In, First Out (Queue)

  • Ordered - Maintains insertion order

  • Sorted - Automatically sorted

  • Indexed - Can access by numeric index

  • O(1) - Constant time (very fast)

  • O(log n) - Logarithmic time (fast)

  • O(n) - Linear time (slower with more items)


Guide Complete! You now have a complete collections reference! 📚

Last updated