java.net.URL Should Not Be Used as Map Key or Set Element
ID |
java.url_no_map_set |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Java |
Tags |
best-practice, reliability |
Description
Reports usage of java.net.URL as a key in Map / HashMap / TreeMap / LinkedHashMap / ConcurrentHashMap or as an element in Set / HashSet / LinkedHashSet / TreeSet.
Rationale
URL.equals() and URL.hashCode() resolve the hostname to an IP address via DNS to compare two URLs. This makes them:
-
Blocking — DNS resolution may take seconds or time out entirely.
-
Non-deterministic — the same hostname can resolve to different IPs depending on DNS caching, load balancing, or network changes.
-
Inconsistent — two logically identical URLs may compare as unequal if DNS returns different addresses at different times.
When URL is used as a Map key or Set element, every get(), put(), contains(), and add() call triggers DNS resolution, turning fast O(1) lookups into slow, flaky operations.
// Bad -- every lookup triggers DNS
Map<URL, String> cache = new HashMap<>();
cache.put(new URL("https://example.com"), "data");
Remediation
Use java.net.URI instead. URI.equals() and URI.hashCode() are purely syntactic comparisons that do not involve DNS resolution.
// Good -- URI comparison is fast and deterministic
Map<URI, String> cache = new HashMap<>();
cache.put(new URI("https://example.com"), "data");