Equality judgment of = = and equals, int and Integer in java
1. The sentence "= = means comparison address and equals means comparison attribute" is wrong
To demonstrate why it is wrong, consider a question: int a = 1; int b = 1; A = = is B true or false? According to the above words, the comparison is the address. Naturally, it is false, but the actual situation is true. It can be concluded that the first half of the above sentence is wrong
code
int a = 1; int b = 1; System.out.println("a==b -> " + (a==b));
result
a==b ->true
2. = = what does it really mean
Conceptually:
- Basic data type: the variable name points to a specific value
- Reference type: the variable name points to the memory address where the data is stored, that is, the variable name points to the hash value
In terms of memory construction:
- Basic data type: once the variable is declared, the jvm will immediately allocate memory space to it
- Reference type: when declared, memory will not be allocated immediately, but a memory address is stored to point to the object in memory. The object in memory consists of three parts: object header + instance data + alignment data
When the basic data type uses = = comparison, because the variable name points to a specific value, the comparison is whether the values are equal. When the reference type uses = = comparison, because the variable name points to a memory address, the two addresses are compared, resulting in the error that = = is the comparison address.
3. The equals method is used for reference type comparison. The basic data type has no equals method
The equals method is used to compare reference types. The basic data type does not have an equals method. It comes from the ancestor Object class of all classes. To judge whether the member variables are equal, use the equals method. The equals method needs to be rewritten to compare whether each member variable is equal.
4. "Rewriting the equals method requires rewriting the hashCode method" is also wrong
Since the equals method is rewritten, we can judge whether the member variables are equal. Why rewrite the hashCode method? This involves the application of HashMap and HashSet. Take HashMap as an example. We all know that HashMap is a non repetitive data structure. We use the Key value method to determine whether to add elements by judging whether the Key values are equal, Here comes the question of Key comparison. Here comes another question, even how keys are compared
Key comparison problem
- The first comparison is hashCode
- The second comparison is the member variable
Source code:
public boolean containsKey(Object key) { return getNode(hash(key), key) != null; } final Node<K,V> getNode(int hash, Object key) { Node<K,V>[] tab; Node<K,V> first, e; int n; K k; if ((tab = table) != null && (n = tab.length) > 0 && (first = tab[(n - 1) & hash]) != null) { if (first.hash == hash && // always check first node ((k = first.key) == key || (key != null && key.equals(k)))) return first; if ((e = first.next) != null) { if (first instanceof TreeNode) return ((TreeNode<K,V>)first).getTreeNode(hash, key); do { if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) return e; } while ((e = e.next) != null); } } return null; } static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
You can see that hashCode is compared first and equals is used to compare member variables
To sum up, the result is that rewriting equals method and rewriting hashCode method have no Half Penny relationship
5. IntegerCache caches numbers from - 128 to 127
- Source code
private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }
In order to save memory and speed up the operation, the jvm caches the number of - 128127. Here, the number in the range is automatically boxed (that is, valueOf(int i)) will be taken from the cache, so it is the same number, that is = = is true, and the number outside the range = = is false.