Although JAVA does not directly support associating Arrays-any object can be used as an index array-
ObjectClass
hashCode()The method clearly indicates the expected wide application
HashMap(And its predecessors)
Hashtable). In ideal cases, the efficient insertion and retrieval of containers based on hashes are provided. The support of hashes in object mode can promote the development and use of hashes-based containers.
Define object equality
ObjectThere are two ways to deduce the object identifier:
equals()And
hashCode(). In general, if you ignore either of them, you must ignore both of them at the same time, because there must be a crucial relationship between the two. In special cases
equals()Method. If two objects are equal, they must have the same
hashCode()Value (although this is not true ).
For a specific class
equals()In the left-side of implementer.
equals()What it means is part of its design work.
ObjectThe following equation is referenced in the provided default implementation:
public boolean equals(Object obj) { return (this == obj); }
|
In this default implementation, the two references are equal only when they reference the same object. Similarly,
ObjectProvided
hashCode()By default, the object memory address is mapped to an integer. In some architectures, the address space is larger
intValue range. Two different objects have the same
hashCode()Yes. If you ignore
hashCode(), You can still use
System.identityHashCode()Method.
Ignore equals ()-simple instance
By default,
equals()And
hashCode()Logo-based implementation is reasonable, but for some classes, they want to relax the definition of equations. For example,
IntegerClass Definition
equals()Similar to the following:
public boolean equals(Object obj) { return (obj instanceof Integer && intValue() == ((Integer) obj).intValue()); }
|
In this definition, only when the two values contain the same integer
IntegerObjects are equal. The combination will not be modifiable
Integer, Which enables the use
IntegerAs
HashMapIs feasible. This value-based equal method can be used by all original encapsulation classes in the Java class library, such
Integer,
Float,
CharacterAnd
BooleanAnd
String(If two
StringObjects that contain characters in the same order are equal ). Because these classes are unchangeable and can be implemented
hashCode()And
equals()They can all be used as good hash keywords.
Why ignore equals () and hashcode ()?
If
IntegerIgnore
equals()And
hashCode()What will happen? If we have never
HashMapOr other hash-based sets.
IntegerAs a keyword, nothing happens. However
In hashmapUse this type
IntegerObjects as keywords cannot be reliably retrieved unless
get()Used in the call and
put()Similar
IntegerInstance. This requires that only the corresponding integer values can be used in our entire program.
IntegerAn instance of the object. Needless to say, this method is extremely inconvenient and has frequent errors.
ObjectInterface contract.
equals()The two objects are equal, so they must have the same
hashCode()Value. When the entire recognition capability is included in
equals()Why does our root object class need
hashCode()?
hashCode()The method is purely used to improve efficiency. Java platform designers predict the importance of the collection class in typical Java applications-for example
Hashtable,
HashMapAnd
HashSetAnd use
equals()Comparing with many objects is very expensive in computing. Make all Java objects supported
hashCode()Combined with a hash-based set, you can effectively store and retrieve data.
Implement equals () and hashcode () Requirements
Implementation
equals()And
hashCode()There are some restrictions,
ObjectThese restrictions are listed in the file. Especially
equals()The method must display the following attributes:
- Handle ry: two references,
aAnd
b,
a.equals(b) if and only if b.equals(a)
- Reflexivity: all non-empty references,
a.equals(a)
- Transiti.pdf: If
a.equals(b)And
b.equals(c), Then
a.equals(c)
- Consistency
hashCode(): Two equal objects must have the same
hashCode()Value
ObjectIs not explicitly required
equals()And
hashCode()Required
Consistent-- Their results will be the same in subsequent calls, assuming that "No information used in object equality comparison is changed ." It sounds like "The calculation results will not change unless the actual situation is the case ." This Fuzzy statement is generally interpreted as equal and hash value calculation should be the object's deterministic function, rather than other.
What does object equality mean?
It is easy for people to meet the object class specification
equals()
And
hashCode()
. Determine whether or not and how to ignore
equals()In addition to judgment, other requirements are also required. In a simple unrecoverable value class, for example
Integer(In fact, almost all the classes that cannot be modified), the choice is quite obvious --
Equality should be based on the equality of the basic object state. In
IntegerIn this case, the unique state of an object is a basic integer.
For modifiable objects, the answer is not always so clear.
equals()
And
hashCode()Should the status of the object be based on the identifier of the object (such as the default implementation) or the object (such as integer and string )? No simple answer --
It depends on the plan of the class. For
ListAnd
MapFor such containers, people are arguing about this. Most classes in the Java class library, including the container class. errors are provided based on the object status.
equals()And
hashCode()Implementation.
If
hashCode()
Values can be changed based on their statuses. When using such objects as keywords in a hash-based set, we must note that when they are used as hash keywords, we are not allowed to change their shape.
Status. All hash-based set assumptions do not change when the object's hash value is used as a key word in the set. If its hash code is changed when the keyword is in the Set, some unpredictable and
Confusing results. This is usually not a problem in practice --
We do not often use imagesListSuch modifiable object
HashMapKeyword.
A simple example of modifiable class is point, which is defined according to the state.
equals()And
hashCode(). If two
Point
The object references the same
(x, y)Coordinates,
PointThe hash value of comes from
xAnd
yThe IEEE 754-bit pairs of coordinate values are equal.
For complex classes,
equals()And
hashCode()May even be affected by superclass or interface. For example,
ListThe interface requires that if only one object is
List,And they have the same elements in the same order (from the elements
Object.equals()
Definition ),
ListThe object is equal to another object.
hashCode()More special -- list
hashCode()The value must meet the following calculation criteria:
hashCode = 1; Iterator i = list.iterator(); while (i.hasNext()) { Object obj = i.next(); hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode()); }
|
Not only does the hash value depend on the content of the list, but it also specifies a special algorithm that combines the hash value of each element. (
StringClass rules similar algorithms for computing
String.)
Compile your own equals () and hashcode () Methods
Ignore the default
equals()The method is relatively simple, but ignore ignored
equals()
The method is extremely tricky. When ignore
equals()You should always
equals()To help users who want to correctly extend your class.
As a simple example, consider the following classes:
class A { final B someNonNullField; C someOtherField; int someNonStateField; }
|
How should we compile
equals()? This method applies to many situations:
public boolean equals(Object other) { // Not strictly necessary, but often a good optimization if (this == other) return true; if (!(other instanceof A)) return false; A otherA = (A) other; return (someNonNullField.equals(otherA.someNonNullField)) && ((someOtherField == null) ? otherA.someOtherField == null : someOtherField.equals(otherA.someOtherField))); }
|
Now we have defined
equals(), Which must be defined in a uniform way.
hashCode(). A uniform but not always valid definition
hashCode()The method is as follows:
public int hashCode() { return 0; }
|
This method will generate a large number of entries and significantly reduce
HashMapS performance, but it complies with specifications. A more reasonable
hashCode()The implementation should be like this:
public int hashCode() { int hash = 1; hash = hash * 31 + someNonNullField.hashCode(); hash = hash * 31 + (someOtherField == null ? 0 : someOtherField.hashCode()); return hash; }
|
Note: Both of these implementations reduce the class status Field
equals()Or
hashCode()The calculation capability of the method is proportional. Depending on the class you use, you may want to lower
equals()Or
hashCode()Computing power of the function. For Original fields, the Helper function is available in the relevant encapsulation class to help create hash values, as shown in
Float.floatToIntBits.
Write a perfect
equals()The method is unrealistic. Generally, when an extension is ignored
equals()When instantiable class of, ignore
equals()It is impractical, and the writing will be ignored.
equals()Methods (such as in abstract classes) are different from writing for specific classes.
equals()Method. For more information about instances and descriptions, see
Valid Java programming language guide, Item 7
(
References ).
To be improved?
Constructing the hash Method to the root object class of the Java class library is a wise design compromise --
It makes the use of hash-based containers so simple and efficient. However, many people have criticized the methods and implementation of hash algorithms and object equality in Java class libraries.
java.utilThe hash-based containers in are very convenient and easy to use, but may not be suitable for applications that require high performance. While most of them will not change, you must consider these factors when designing applications that depend heavily on the efficiency of hashed containers, including:
- The hash range is too small. Use
intInstead
longAs
hashCode()The return type increases the probability of hash conflicts.
- Bad hash value allocation. The hash values of short strings and small integers are their own small integers, which are close to the hash values of other "adjacent" objects. A well-behaved hash function distributes hash values more evenly within the hash range.
- Undefined hash operation. Although some classes, such
StringAnd
List, Defines the hash algorithm used to combine the hash value of its element into a hash value, however, the language specification does not define any method for combining hash values of multiple objects into new hash values. We are at the front
Compile your own equals () and hashcode () methods.
List,
StringOr instance type
AIt is easy to use, but it is far from perfect in arithmetic. The class library does not provide any hash algorithm for easy implementation, it can simplify more advanced
hashCode()Implementation creation.
- When the extension has been ignored
equals()It is difficult to compile the instantiable class
equals(). When the extension has been ignored
equals()Instantiable class, defined
equals()Neither of the "obvious" methods can meet
equals()Symmetric or pass-through requirements of methods. This means that when you ignore
equals()You must understand the structure and implementation details of the class you are extending, or even expose confidential fields in the basic class, which violates the object-oriented design principles.