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");