The legacy collection classes are Vector, Stack, Hashtable, Dictionary, and the Enumeration interface — they predate the Collections Framework (which arrived in Java 1.2) and were retrofitted to implement the new interfaces for compatibility. They're considered "legacy" because they make poor default choices: synchronized-by-default, inconsistent naming, and weaker contracts.
The Cast of Characters
Vector<E>— a synchronized resizable array, the ancestor ofArrayList.Stack<E> extends Vector<E>— LIFO stack. ExtendsVector, which is itself a design mistake (Stackshouldn't be aList).Hashtable<K,V>— synchronized hash map, ancestor ofHashMap. Note the lowercaset— historically inconsistent.Dictionary<K,V>— abstract base class for key-value structures, predatesMap. Now obsolete.Enumeration<E>— predecessor ofIterator, with justhasMoreElements()/nextElement(). Noremove.Properties extends Hashtable<Object,Object>— still in active use for config files, but itsHashtableparentage leaks through.
Why "Legacy"?
// Legacy
Vector<String> v = new Vector<>();
Hashtable<String,Integer> h = new Hashtable<>();
Stack<Integer> s = new Stack<>();
// Modern equivalents
List<String> v2 = new ArrayList<>();
Map<String,Integer> h2 = new HashMap<>();
Deque<Integer> s2 = new ArrayDeque<>(); // ArrayDeque is the recommended stack
The problems with the legacy types:
- Always synchronized — every method on
VectorandHashtableis synchronized, paying a cost most code doesn't need. Modern code prefers unsynchronized defaults (ArrayList,HashMap) and opts in to concurrency viaConcurrentHashMaporCopyOnWriteArrayList. - Null hostility inconsistency —
Hashtablerejects null keys and null values (throwingNullPointerException);HashMapallows both. Different rules, same shape — a footgun. - Stack extends Vector — meaning a
Stackis also aList, so you canget(0)oradd(5, "x")into the middle of a "stack." A naming-driven mistake. - Weaker iteration —
Enumerationpredates fail-fastIterator, has noremove, and isn't part ofIterable. - Inconsistent naming —
Hashtable(lowercase t) vs.HashMap,elementAtvs.get,addElementvs.add.
When You Still See Them
Properties remains common because System.getProperties() returns one and config-file APIs accept it. Hashtable may appear in third-party reflection-heavy code. Otherwise, treat all five as read-only encounters: understand them when you meet them, never reach for them in new code.