I found a very strange problem when debug was chasing the stack.
I use IE8 and Google's browser to access the same address
The action's scope= "session" also sets the
and two browser-submitted parameter map is also independent of each other
But it's weird. The hashmap of a two-action object is different
But the hash value of their object variable paratermap is actually a
I don't understand!
(Find out the reason to find that this problem is actually a very long time not to mention the basic problem)
But I found a friend on the internet who said that the problem had caused a bug
The Hashcode () method in Java is a very special place.
The hashcode in the object class is a local method
public native int hashcode ();
Even if you look at the source code you can not find its implementation, because it is not a Java method of writing
This method compares the memory addresses of two objects for equality
6.1 Hashcode method of overwrite
Many of the subclasses in the API override this method, the most typical of which should be the string class, in the String class
/**
* Returns A hash code for this string. The hash code for a
* <code>String</code> object is computed as
* <blockquote><pre>
* s[0]*31^ (n-1) + s[1]*31^ (n-2) + ... + s[n-1]
* </pre></blockquote>
* Using <code>int</code> arithmetic, where <code>s[i]</code> is the
* <i>i</i>th character of the string, <code>n</code> is the length of
* The string, and <code>^</code> indicates exponentiation.
* (The hash value of the empty string is zero.)
*
* @return A hash code value for this object.
*/
public int hashcode () {
int h = hash;
if (h = = 0) {
int off = offset;
Char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
H = 31*h + val[off++];
}
hash = h;
}
return h;
}
As you can see, the string class uses its value values as arguments and then operations to derive hashcode
In other words, if a string of the same value is not an object, the hash value is all equal
In other words, run the following code and you'll see exactly the same hashcode.
As for the two different computers will not be the same I do not know, because the off offset of the participating operations may be different
6.2 Careful use of the HashMap object's Hashcode
This is an extremely dangerous act!
Public final int hashcode () {
Return (Key==null 0:key.hashcode ()) ^
(Value==null 0:value.hashcode ());
}
In the HashMap class, if the internal object of the HashMap object is empty, the hashcode must be 0
If not empty, iterates through all objects in the container
Then take the key hashcode and value of the Hashcode bitwise XOR, and then add them in turn
In other words, if your two HashMap key and value are all the same, then their hashcode is the same
HashMap map1 = new HashMap ();
Map1.put ("Test", "TestValue");
Map1.put ("Test1", "testValue1");
Map1.put ("Test2", "testValue2");
HashMap map2 = new HashMap ();
Map2.put ("Test", "TestValue");
Map2.put ("Test1", "testValue1");
Map2.put ("Test2", "testValue2");
System.out.println (Map1.hashcode ());
System.out.println (Map2.hashcode ());
The output values of the following code are equal
So! At any time! Do not use HashMap or some special container hashcode as key to cache
The following things go from
http://dingjob.javaeye.com/blog/696768
http://dingjob.javaeye.com/blog/696768
Two connections are written because the add connection on Douban carries the A-href anchor tag.
I just want to see if I don't use this it will automatically determine the link address and then add it yourself
Very satisfied, watercress do not brain remnant ╮ (╯_╰) ╭
2010-06-22
A major bug caused by the hashcode of the map to cache key values
Article Category: Java programming
Phenomenon:
Billing and account interactions are interactive via map, and the basic data format is as follows {"pp900_88", "pp900_61", 2 ... }
In the case of different values, more data returns the same price result, resulting in incorrect price calculation.
Application Scenarios:
When the product calculates the price, caches the price result data using the cache, the key value of the cache is the hashcode of the incoming map, the intention is to achieve the exact same map incoming value from the cache to fetch data, reduce the database access.
Cause Analysis:
One. Simulate the online application with the following code:
Java code
1.public static void Main (string[] args) {
2. HashMap map = new HashMap ();
3.
4. for (int i = 0; i <; i + +) {
5.
6. HashMap m1 = new HashMap ();
7.
8. M1.put ("pp900_88", I);
9.
Ten. M1.put ("pp900_59", 30);
11.
M1.put ("pp900_62", 6);
13.
M1.put ("pp900_63", 4);
15.
M1.put ("pp900_60", "Y");
17.
M1.put ("pp900_61", I);
19.
int hs = M1.hashcode ();
21st.
Map.put (HS, Map.get (HS) + "," +i);
//System.out.println (i+ "= = =" +m1.hashcode ());
24.}
System.out.println (Map.size ());
SYSTEM.OUT.PRINTLN (map);
27.}
public static void Main (string[] args) {
HashMap map = new HashMap ();
for (int i = 0; i <; i + +) {
HashMap m1 = new HashMap ();
M1.put ("pp900_88", I);
M1.put ("pp900_59", 30);
M1.put ("pp900_62", 6);
M1.put ("pp900_63", 4);
M1.put ("pp900_60", "Y");
M1.put ("pp900_61", I);
int hs = M1.hashcode ();
Map.put (HS, Map.get (HS) + "," +i);
System.out.println (i+ "= = =" +m1.hashcode ());
}
System.out.println (Map.size ());
SYSTEM.OUT.PRINTLN (map);
The results are as follows:
Java code
1.{-479160017=null,56,57,58,59,60,61,62,63,
2. -479160049=null,40,41,42,43,44,45,46,47,
3. -479160033=null,48,49,50,51,52,53,54,55,
4. -479160129=null,0,1,2,3,4,5,6,7,64,65,66,67,68,69,70,71,
5. -479160097=null,16,17,18,19,20,21,22,23,80,81,82,83,84,85,86,87,
6. -479160113=null,8,9,10,11,12,13,14,15,72,73,74,75,76,77,78,79,
7. -479160065=null,32,33,34,35,36,37,38,39,96,97,98,99,
8. -479160081=null,24,25,26,27,28,29,30,31,88,89,90,91,92,93,94,95}
{ -479160017=null,56,57,58,59,60,61,62,63,
-479160049=NULL,40,41,42,43,44,45,46,47,
-479160033=null,48,49,50,51,52,53,54,55,
-479160129=NULL,0,1,2,3,4,5,6,7,64,65,66,67,68,69,70,71,
-479160097=null,16,17,18,19,20,21,22,23,80,81,82,83,84,85,86,87,
-479160113=null,8,9,10,11,12,13,14,15,72,73,74,75,76,77,78,79,
-479160065=null,32,33,34,35,36,37,38,39,96,97,98,99,
-479160081=NULL,24,25,26,27,28,29,30,31,88,89,90,91,92,93,94,95}
As can be seen, repetition is very regular, 7, 8 consecutive data are duplicated, of course, in real case the repetition probability is not so high (because the other Key-value value of map is unlikely to be the same)
Two. Analysis of the generation of hashcode
The HashMap Hashcode calculates the hashcode based on the key and value values, and finally adds the hashcode values of each element, i.e.
Java code
1.public final int hashcode () {
2. Return (Key==null 0:key.hashcode ()) ^
3. (Value==null 0:value.hashcode ());
4.}
Public final int hashcode () {
Return (Key==null 0:key.hashcode ()) ^
(Value==null 0:value.hashcode ());
}
With M1.put ("pp900_88", 1); M1.put ("pp900_61", 1);
M1.put ("pp900_88", 2); M1.put ("pp900_61", 2); For example: The hashcode value of the obtained Key-value is as follows
Key key hashcode value of Hashcode map Hashcode (Key^value)
pp900_88-79859962 1-79859961
pp900_61-79860031 1-79860032
pp900_88-79859962 2-79859964
pp900_61-79860031 2-79860029
Obviously according to the map hash value algorithm, map hashcode add: The first row + the second row = the third row + the fourth row, this produces the duplicate data also inevitably, because Hashcode originally did not guarantee the different input value does not produce the same result. The JSL constraint is that for the same object, the same hashcode must be produced.
Conclusions and improvement measures:
1. Caching of results is not recommended, resulting caches can cause many problems, such as which data changes need to be refreshed and which caches are best cached for the original record value.
The 2.key value does not use the hashcode algorithm and changes directly to string concatenation using individual key-value.
Never misuse the Hashcode method in Java