blob: abbff4735c044e99a6e4087d7c98ab202fedb3cf [file] [log] [blame] [view] [edit]
Some JDK APIs are obsolete and have preferred alternatives.
## `LinkedList`
`LinkedList` almost never out-performs `ArrayList` or `ArrayDeque`[^1]. If you
are using `LinkedList` as a list, prefer `ArrayList`. If you are using
`LinkedList` as a stack or queue/deque, prefer `ArrayDeque`.
Migration gotcha: `LinkedList` permits `null` elements; `ArrayDeque` rejects
them. The documentation for `Deque` strongly discourages users from inserting
`null`, even into implementations that permit it. So, if you are using a
`LinkedList` for this purpose, you should likely stop, and you will _need_ to
stop in order to migrate to `ArrayDeque`.
## `Vector`
`Vector` performs synchronization that is usually unnecessary; prefer
`ArrayList`.
If a synchronized collection is necessary, use `Collections.synchronizedList` or
a data structure from `java.util.concurrent`.
## `Hashtable` and `Dictionary`
This is a nonstandard class that predates the Java Collections Framework; prefer
`LinkedHashMap` or `HashMap`.
If synchronization is necessary, `java.util.concurrent.ConcurrentHashMap` is
usually a good choice.
## `java.util.Stack`
`Stack` is a nonstandard class that predates the Java Collections Framework;
prefer `ArrayDeque`.
If a synchronized collection is necessary, use a data structure from
`java.util.concurrent`.
When migrating from `Stack` to `Deque`, note that the `Stack` methods
`push`/`pop`/`peek`/`add`/`iterator` correspond to the `Deque` methods
`addFirst`/`removeFirst`/`peekFirst`/`addFirst`/`descendingIterator`.
## `StringBuffer`
`StringBuffer` performs synchronization that is rarely necessary and has
significant performance overhead. Prefer `StringBuilder`, which does not do
synchronization.
If synchronization is necessary, consider creating an explicit lock object and
using `synchronized` blocks.
## `Enumeration`
An ancient precursor to `Iterator`.
## `SortedSet` and `SortedMap`
Replaced by `NavigableSet` and `NavigableMap` in Java 6.
[^1]: People generally choose `LinkedList` because they want fast insertion and
removal. However, `LinkedList` has slow traversal, and typically you need
to traverse the list to find the place to insert/remove. It turns out that
the cost of traversing to a location in a `LinkedList` is approximately 4x
the cost of copying an element in an `ArrayList`. Thus, `LinkedList`'s
traversal cost dominates and results in poorer performance. More info:
https://stuartmarks.wordpress.com/2015/12/18/some-java-list-benchmarks/
## `Date`
The `Date` API is full of
[major design flaws and pitfalls](https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/)
and should be avoided at all costs. Prefer the `java.time` APIs, specifically,
`java.time.Instant` (for physical time) and `java.time.LocalDate[Time]` (for
civil time).