Java Magic java.net.URL【 translate 】
Recently found a very interesting code segment :
HashSet set = new HashSet();
set.add(new URL("http://google.com"));
System.out.println(set.contains(new URL("http://google.com")));
Thread.sleep(60000);
System.out.println(set.contains(new URL("http://google.com")));
Guess what , The first 3、5 What does the guild output ?
The result must not be true
,true
.
Okay , In most cases, the result may be true, false
.
If you shut down the network and run it again, the result may be :true
,true
了 .
The reason for this is java.net.URL
Class hashCode()
and equals()
The specific implementation of the method results in .
Let’s take a look at it hashCode Method :
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
hashCode = handler.hashCode(this);
return hashCode;
}
private int hashCode = -1;
We can see hashCode It’s a member variable , Calculate only once .
Be careful ,java.net.URL
Class is immutable .
that handler What is it ? yes URLStreamHandler
A subclass of , Depends on the agreement (file、http、ftp…).
If you are interested, please check : java.net.URLStreamHandler#hashCode
The logic of .
Let’s take a look at URL.hashCode()
Of javadoc explain :
Based on Web site comparison , It’s a blocking operation !
OMG!! It’s a blocking operation !!
Another exciting thing is ,handler Will parse the host ip Address to calculate the hash value . If it doesn’t work , Based on the domain name http://google.com
Calculate the hash value .
If ip Is dynamic , Or there is request load balancing , Then the host’s ip It’s also dynamic —— So we might get out of sync hash values , In this way HashSet Namely 2 Different examples of .
It’s not good at all , By the way ,hashCode and equals The performance is terrible —— because URLStreamHandler Will open URLConnection.
So how to avoid this happening ?
- Use
java.net.URI
Replacejava.net.URL
; This is not the best choice , But there is also a definite hash implementation . - Don’t use… In collections
java.net.URL
, If you really want to do this , It is recommended to use a representative URL Of String Objects in the collection . - When you calculate the hash value , Broken net !!!—— I’m kidding …
- Write your own URLStreamHandler Subclasses implement the appropriate hashCode Method .
appendix
Reference resources :http://mishadoff.com/blog/java-magic-part-1-java-dot-net-dot-url/