## Hash Principle

First of all, before we define Java hashcode, we need to understand what is hashing and what is it for. Hashing is a process of applying a hash function to some data. A hash function is just a mathematical function. Don’t worry about this! “Mathematical” is not always means “complicated”. Here it means only that we have some data and a certain rule that maps the data into a set of characters (code). For example, it could be a hexadecimal cipher. We have some data of any size at the input, and apply a hash function to it. At the output, we get a fixed-size data, say, 32 characters. Usually, that kind of function converts a big piece of data into a small integer value. The result of this function work is called a hash code. Hash functions are widely used in cryptography, and some other areas too. Hash functions can be different, but they all have certain properties:
• A particular object has a particular hash code.
• If two objects are equal, their hash codes are the same. The reverse is not true.
• If the hash codes are different, then the objects are not equal for sure.
• Different objects may have the same hash code. However, it is a very unlikely event. At this point, we have a collision, a situation, where we can lose data.
The "proper" hash function minimizes the probability of collisions.

## HashCode in Java

In Java hash function is usually connected to `hashCode()`. Precisely, the result of applying a hash function to an Object is hashCode. Every Java object has a hash code. In general Hash Code is a number calculated by the `hashCode()` method of the `Object` class. Usually, programmers override this method for their objects as well as related to `hashCode()` the `equals()` method for more efficient processing of specific data. The `hashCode()` method returns an int (4 bytes) value, which is a numeric representation of the object. This hash code is used, for example, by collections for more efficient storage of data and, accordingly, faster access to them. By default, the `hashCode()` function for an object returns the number of the memory cell where the object is stored. Therefore, if no changes are made to the application code, then the function should return the same value. If the code changes slightly, the hashCode value also changes. What hashCode Java uses for? First of all Java Hash codes helps programs run faster. For example, if we compare two objects `o1` and `o2` of some type, the operation `o1.equals(o2)` takes about 20 times more time than `o1.hashCode() == o2.hashCode()`.

## Java equals()

In the parent class `Object`, along with the `hashCode()` method, there is also `equals()`, the function that is used to check the equality of two objects. The default implementation of this function simply checks the links of two objects for their equivalence. `equals()` and `hashCode()` have their contract, so if you override the one, you should override the second for not breaking this contract.

## Example, what is hashcode in Java

Let’s create a class `Character` with one field — `name`. After that, we create two objects of `Character` class, `character1`, and `character2` and set them the same name. If we use default `hashCode()` and `equals()` of `Object` class, we’ve definitely got the different, not equal objects.That’s how hashcode in Java works. They will have different hashCodes because they are in different memory cells and `equals()` operation result will be false.
``````import java.util.Objects;

public class Character {
private String Name;

public Character(String name) {
Name = name;
}

public String getName() {
return Name;
}

public void setName(String name) {
Name = name;
}

public static void main(String[] args) {
Character character1 = new Character("Arnold");
System.out.println(character1.getName());
System.out.println(character1.hashCode());
Character character2 = new Character("Arnold");
System.out.println(character2.getName());
System.out.println(character2.hashCode());
System.out.println(character2.equals(character1));
}
}``````
The result of running the program:
``````Arnold
1595428806
Arnold
1072408673
false``````
Two 10-digit numbers in the console are hashCodes. What if we want to have Objects equivalent if they have the same names? What should we do? The answer: we should override `hashCode()` and `equals()` methods of `Object` class for our `Character` class. We could do it automatically in IDEA IDE, just press alt + insert on your keyboard and choose Generate -> equals() and hashCode(). In the case of our example we’ve got the next code:
``````import java.util.Objects;

public class Character {
private String Name;

public Character(String name) {
Name = name;
}

public String getName() {
return Name;
}

public void setName(String name) {
Name = name;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Character)) return false;

Character character = (Character) o;

return getName() != null ? getName().equals(character.getName()) : character.getName() == null;
}

@Override
public int hashCode() {
return getName() != null ? getName().hashCode() : 0;
}

public static void main(String[] args) {
Character character1 = new Character("Arnold");
System.out.println(character1.getName());
System.out.println(character1.hashCode());
Character character2 = new Character("Arnold");
System.out.println(character2.getName());
System.out.println(character2.hashCode());
System.out.println(character2.equals(character1));
}
}``````
The result of running this code:
``````Arnold
1969563338
Arnold
1969563338
true``````
So now the program identifies our objects as equals and they have the same hash codes.

## Java hashcode example: your own hashcode and equals

You may also create your own `equals()` and `hashCode()` realizations, but be careful remembering of collisions minimization of hashcodes. Here is an example of our own `hashCode()` and `equals()` methods in `Student` class:
``````import java.util.Date;

public class Student {
String surname;
String name;
String secondName;
Long birthday; // Long instead of long is used by Gson/Jackson json parsers and various orm databases

public Student(String surname, String name, String secondName, Date birthday ){
this.surname = surname;
this.name = name;
this.secondName = secondName;
this.birthday = birthday == null ? 0 : birthday.getTime();
}
//Java hashcode example
@Override
public int hashCode(){
//TODO: check for nulls
//return surname.hashCode() ^ name.hashCode() ^ secondName.hashCode() ^ (birthday.hashCode());
return (surname + name + secondName + birthday).hashCode();
}
@Override
public boolean equals(Object other_) {
Student other = (Student)other_;
return (surname == null || surname.equals(other.surname) )
&& (name == null || name.equals(other.name))
&& (secondName == null || secondName.equals(other.secondName))
&& (birthday == null || birthday.equals(other.birthday));
}
}``````
And the `Main` class to demonstrate their work:
``````import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;

public class Main {
static HashMap<Student, Integer> cache = new HashMap<Student, Integer>(); // <person, targetPriority>

public static void main(String[] args) {
Student sarah1 = new Student("Sarah","Connor", "Jane", null);
Student sarah2 = new Student("Sarah","Connor", "Jane", new Date(1970, 01-1, 01));
Student sarah3 = new Student("Sarah","Connor", "Jane", new Date(1959, 02-1, 28)); // date not exists
Student john = new Student("John","Connor", "Kyle", new Date(1985, 02-1, 28)); // date not exists
Student johnny = new Student("John","Connor", "Kyle", new Date(1985, 02-1, 28)); // date not exists
System.out.println(john.hashCode());
System.out.println(johnny.hashCode());
System.out.println(sarah1.hashCode());
System.out.println();
cache.put(sarah1, 1);
cache.put(sarah2, 2);
cache.put(sarah3, 3);
System.out.println(new Date(sarah1.birthday));
System.out.println();
cache.put(john, 5);
System.out.println(cache.get(john));
System.out.println(cache.get(johnny));
cache.put(johnny, 7);
System.out.println(cache.get(john));
System.out.println(cache.get(johnny));
}
}``````

## What hashCode is used for?

First of all Hash codes helps programs run faster. For example, if we compare two objects `o1` and `o2` of some type, the operation `o1.equals(o2)` takes about 20 times more time than o1.hashCode() == o2.hashCode(). In Java hashing principle stands behind some popular collections `HashMap`, `HashSet` and `HashTable`.

## Conclusion

Every Java Object has methods `hashCode()` and `equals()` inherited from `Object` class. To get a good working equality mechanism, you’d better override `hashcode()` and `equals()` methods for your own Classes. Using hash codes makes programs run faster.