In this post, I am going to explain why you should be cautious while using the equals method of URL class.
How URL equals method works?
As per the
Java documentation, equals method documented like below.
That means, while checking two urls equality, Java performs a blocking DNS lookup operation to resolve hostname to IP address and then compare the ip addresses.
URL url1 = new URL("https://abc.test.com");
URL url2 = new URL("https://xyz.test.com");
Let's say both of these domains map to same IP address.
https://abc.test.com => 246.103.91.15
https://xyz.test.com => 246.103.91.15
Now when you compare url1 with url2 using equals method, it returns true. But both are different domains, I am expecting it to be false.
Apart from this, Since two url comparison using equals method perform a blocking DNS lookup operation to resolve the hostname, it takes lot of time for the comparison. In this case better to use URI (instead of URL) to compare two urls.
Let’s see it with an example.
URLEquals.java
package com.sample.app.net;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class URLEquals {
public static List<URL> urls(List<String> urls) throws MalformedURLException {
List<URL> urlList = new ArrayList<>();
for (String url : urls) {
urlList.add(new URL(url));
}
return urlList;
}
public static List<URI> uris(List<String> urls) throws MalformedURLException, URISyntaxException {
List<URI> uriList = new ArrayList<>();
for (String url : urls) {
uriList.add(new URI(url));
}
return uriList;
}
public static void main(String args[]) throws URISyntaxException, MalformedURLException {
boolean state = false;
List<String> urlStrs = Arrays.asList("https://google.com", "https://youtube.com", "https://facebook.com",
"https://www.wikipedia.org/", "https://twitter.com/", "https://www.quora.com/",
"https://www.similarweb.com/", "https://hypestat.com/", "https://in.search.yahoo.com/",
"https://www.amazon.com/", "https://www.walmart.com/", "https://javarevisited.blogspot.com/",
"https://javarevisited.blogspot.com/", "https://javahungry.blogspot.com/",
"https://javabypatel.blogspot.com/", "https://dnb-java.blogspot.com/p/home.html",
"https://self-learning-java-tutorial.blogspot.com/", "https://javadevelopersguide.blogspot.com/",
"https://javaknowhow.blogspot.com/", "https://javabasictoadvanced.blogspot.com/",
"http://biemond.blogspot.com/", "https://javaworld-abhinav.blogspot.com/",
"http://randomthoughtsonjavaprogramming.blogspot.com/", "https://javadiscover.blogspot.com/",
"http://marxsoftware.blogspot.com/", "http://craftingjava.blogspot.com/",
"https://www.java-success.com/", "https://javasolutionsguide.blogspot.com/",
"https://ebclj.blogspot.com/", "https://www.tabnine.com/", "https://www.linkedin.com/",
"https://github.com/", "https://www.overops.com/", "https://blog.javapapo.com/",
"https://www.facebook.com/", "https://www.buggybread.com", "https://www.baeldung.com/",
"https://www.onlyfullstack.com/", "https://apexapps.oracle.com/", "https://guava.dev/",
"https://www.java67.com/", "https://blog.feedspot.com/", "https://javapapers.com/",
"https://www.ideamotive.co/", "https://blogs.sap.com/", "https://www.eclipse.org/",
"https://www.sololearn.com/", "https://brainly.in/", "https://www.javacodegeeks.com/",
"https://freecomputerbooks.com/", "https://www.freecodecamp.org/", "https://en.wikipedia.org/");
List<URL> urls = urls(urlStrs);
long time1 = System.currentTimeMillis();
for (URL url1 : urls) {
for (URL url2 : urls) {
if (url1.equals(url2)) {
// System.out.println(url1 + " and " + url2 + " are equal ");
state = true;// some dummy action
}
}
}
long time2 = System.currentTimeMillis();
List<URI> uris = uris(urlStrs);
long time3 = System.currentTimeMillis();
for (URI uri1 : uris) {
for (URI uri2 : uris) {
if (uri1.equals(uri2)) {
// System.out.println(uri1 + " and " + uri2 + " are equal ");
state = true;
}
}
}
long time4 = System.currentTimeMillis();
System.out.println("url comparison take " + (time2 - time1) + " milliseconds");
System.out.println("uri comparison take " + (time4 - time3) + " milliseconds");
}
}
Output
url comparison take 13478 milliseconds uri comparison take 2 milliseconds
How URI equals method works?
Two uris are considered to be equals, if
a. Their schemes must either both be undefined or else be equal without regard to case.
b. Their fragments must either both be undefined or else be equal.
c. For two opaque URIs to be considered equal, their scheme-specific parts must be equal.
d. For two hierarchical URIs to be considered equal, their paths must be equal and their queries must either both be undefined or else be equal. Their authorities must either both be undefined, or both be registry-based, or both be server-based. If their authorities are defined and are registry-based, then they must be equal. If their authorities are defined and are server-based, then their hosts must be equal without regard to case, their port numbers must be equal, and their user-information components must be equal.
No comments:
Post a Comment