Navigation
Java Full Course: Mastering the Language Vector Class in Java
Vector Class in Java
(Complete Notes | Beginner to Advanced | Professional & Exam-Oriented | Masterclass)
1. What is a Vector?
The Vector class implements a growable array of objects. Like a standard array, it contains components that can be accessed using an integer index. However, unlike arrays, a Vector can grow or shrink as needed to accommodate adding and removing items.
Vectors are part of the Java Collections Framework and are found in the java.util package. Since Java 1.2, Vector has been retrofitted to implement the List interface, making it a member of the Collections Framework.
Key characteristics:
- Dynamic sizing – Automatically grows and shrinks as elements are added or removed
- Synchronized – All methods are thread-safe, making it suitable for multi-threaded environments
- Legacy class – Existed since Java 1.0, later adapted to work with the Collections Framework
- RandomAccess – Implements the
RandomAccessmarker interface, indicating efficient index-based access - Type-safe – Uses generics (since Java 5) to ensure type safety
2. Class Hierarchy and Declaration
Class declaration:
Where E is the type of elements stored in the vector.
Direct known subclass:
- Stack – extends
Vectorto implement a last-in-first-out (LIFO) stack
3. Constructors
Vector provides four constructors with different initialization options:
| Constructor | Description |
|---|---|
Vector() | Creates an empty vector with an initial capacity of 10 and a capacity increment of 0 |
Vector(int initialCapacity) | Creates an empty vector with the specified initial capacity; capacity increment is 0 |
Vector(int initialCapacity, int capacityIncrement) | Creates an empty vector with the specified initial capacity and capacity increment |
Vector(Collection<? extends E> c) | Creates a vector containing the elements of the specified collection in the order returned by the collection's iterator |
Examples:
Common exceptions:
IllegalArgumentException– ifinitialCapacityis negativeNullPointerException– if the specified collection is null
4. Protected Fields
Vector maintains three protected fields that manage its internal storage:
| Field | Description |
|---|---|
protected Object[] elementData | The array buffer storing vector components; its length is the vector's capacity |
protected int elementCount | The number of valid components in the vector (actual size) |
protected int capacityIncrement | The amount by which capacity increases when the vector overflows; if ≤ 0, capacity doubles each time |
5. Capacity Management
a) Understanding Capacity vs. Size
- Capacity – The length of the internal array (
elementData.length) - Size (
elementCount) – The number of elements actually stored in the vector
The capacity is always at least as large as the size. When elements are added beyond the current capacity, the vector automatically expands.
b) Growth Policy
The growth behavior depends on capacityIncrement:
Examples:
c) Capacity Management Methods
| Method | Description |
|---|---|
int capacity() | Returns the current capacity of the vector |
void ensureCapacity(int minCapacity) | Increases capacity if necessary to hold at least minCapacity elements |
void trimToSize() | Reduces capacity to match the current size (minimizes memory usage) |
void setSize(int newSize) | Sets the size of the vector; if larger, adds null elements; if smaller, truncates |
Example:
6. Important Methods
a) Adding Elements
| Method | Description |
|---|---|
boolean add(E e) | Appends element to the end; returns true |
void add(int index, E element) | Inserts element at specified position; shifts subsequent elements right |
void addElement(E obj) | Legacy method; adds element to the end |
boolean addAll(Collection<? extends E> c) | Appends all elements from the collection |
boolean addAll(int index, Collection<? extends E> c) | Inserts all elements at specified position |
void insertElementAt(E obj, int index) | Legacy method; inserts element at index |
Example:
b) Accessing Elements
| Method | Description |
|---|---|
E get(int index) | Returns element at specified index |
E elementAt(int index) | Legacy method; returns element at index |
E firstElement() | Returns the first element (index 0) |
E lastElement() | Returns the last element (size-1) |
Iterator<E> iterator() | Returns an iterator over elements |
Enumeration<E> elements() | Returns an enumeration (legacy) |
Example:
c) Removing Elements
| Method | Description |
|---|---|
E remove(int index) | Removes element at index; returns removed element |
boolean remove(Object o) | Removes first occurrence of specified element |
boolean removeAll(Collection<?> c) | Removes all elements contained in the collection |
void removeAllElements() | Removes all elements (legacy) |
boolean removeElement(Object obj) | Legacy method; removes first occurrence |
void removeElementAt(int index) | Legacy method; removes element at index |
void clear() | Removes all elements |
Example:
d) Searching and Checking
| Method | Description |
|---|---|
boolean contains(Object o) | Returns true if vector contains the element |
int indexOf(Object o) | Returns index of first occurrence; -1 if not found |
int indexOf(Object o, int index) | Searches forward from specified index |
int lastIndexOf(Object o) | Returns index of last occurrence |
int lastIndexOf(Object o, int index) | Searches backward from specified index |
boolean isEmpty() | Returns true if vector has no elements |
int size() | Returns number of elements |
Example:
e) Modifying Elements
| Method | Description |
|---|---|
E set(int index, E element) | Replaces element at index; returns old element |
void setElementAt(E obj, int index) | Legacy method; replaces element at index |
void replaceAll(UnaryOperator<E> operator) | Replaces each element with result of applying operator |
Example:
f) Converting and Copying
| Method | Description |
|---|---|
Object[] toArray() | Returns array containing all elements |
<T> T[] toArray(T[] a) | Returns array of specified runtime type |
void copyInto(Object[] anArray) | Copies components into specified array |
Object clone() | Returns a shallow copy of the vector |
String toString() | Returns string representation |
Example:
7. Vector vs. ArrayList
This is one of the most important comparisons to understand when choosing between these two classes.
| Feature | Vector | ArrayList |
|---|---|---|
| Thread Safety | Synchronized (thread-safe) | Not synchronized (not thread-safe) |
| Performance | Slower due to synchronization overhead | Faster in single-threaded environments |
| Growth Policy | Doubles capacity (if increment ≤ 0) or adds increment | Increases by 50% of current capacity |
| Legacy Status | Legacy class (Java 1.0) | Part of Collections Framework (Java 1.2) |
| Iterators | Fail-fast (except Enumeration) | Fail-fast |
| Recommended Use | Multi-threaded environments requiring thread safety | Single-threaded environments or when external synchronization is manageable |
Synchronization explanation:
Vectormethods are synchronized, meaning each method call acquires a lock- This makes
Vectorsafe for concurrent access but introduces performance overhead ArrayListhas no such synchronization, requiring external synchronization if used in multi-threaded contexts
Performance guidance:
- Use
ArrayListin single-threaded applications for better performance - Use
Vectoronly when you specifically need built-in thread safety - For concurrent access with
ArrayList, useCollections.synchronizedList()orCopyOnWriteArrayList
8. Iterators and Fail-Fast Behavior
Vector provides two types of iteration mechanisms with different fail-fast characteristics:
a) Fail-Fast Iterators (iterator(), listIterator())
- These iterators throw
ConcurrentModificationExceptionif the vector is structurally modified (add/remove) after iterator creation, except through the iterator's ownremoveoraddmethods - This behavior helps detect bugs during development
Example:
b) Non-Fail-Fast Enumeration (elements())
- The
Enumerationreturned byelements()is not fail-fast - If the vector is modified after enumeration creation, results are undefined
Example:
9. Complete Working Example
10. When to Use Vector
Use Vector when:
- You need thread-safe collection operations without external synchronization
- You are working with legacy code that expects
Vector - You need to control growth increment precisely (via
capacityIncrement) - You are building a
Stack(Vectoris the parent class ofStack)
Avoid Vector and prefer ArrayList when:
- You are working in a single-threaded environment
- Performance is critical and synchronization overhead is undesirable
- You want to manually control synchronization using
Collections.synchronizedList() - You need better memory efficiency (
Vector's synchronization adds overhead)
Alternative for concurrent scenarios:
CopyOnWriteArrayList– Provides thread safety with better performance for read-heavy workloads
11. Common Pitfalls and Best Practices
| Pitfall | Explanation / Solution |
|---|---|
| Using Vector in single-threaded code | Unnecessary synchronization reduces performance; use ArrayList instead |
| Assuming Enumeration is fail-safe | elements() enumeration is not fail-fast; modification during enumeration leads to undefined behavior |
| Not setting initial capacity | Vectors grow automatically, but growth requires array copying; set capacity appropriately for large datasets |
| Using Vector when only iteration is needed | Consider ArrayList for read-heavy operations |
| Concurrent modification without proper synchronization | Even with Vector's synchronization, iterators are fail-fast; don't modify while iterating |
| Confusing size() with capacity() | size() = number of elements; capacity() = internal array length |
Best Practices:
- Initialize with appropriate capacity – Avoid repeated resizing for large collections
- Use trimToSize() after bulk additions – Reduce memory footprint when growth is complete
- Prefer ArrayList for new development – Use
Vectoronly when thread safety is required - Use enhanced for loop – More readable than
Enumeration - Consider Collections.synchronizedList() – Alternative for thread-safe
ArrayList
12. Key Points to Remember
Vectoris a synchronized, growable array implementation of theListinterface- It is thread-safe – all methods are synchronized
- Default initial capacity is 10, default growth is doubling
- Legacy class that was retrofitted for the Collections Framework (Java 1.2)
- Provides both modern (
Listinterface) and legacy (addElement,elements()) methods - Fail-fast iterators throw
ConcurrentModificationExceptionon concurrent modification Enumerationreturned byelements()is not fail-fast- Use
ArrayListfor single-threaded applications; useVectorwhen thread safety is required - Parent class of
Stack– useStackfor LIFO operations
