Primeiramente, antes de definirmos o hashcode Java, precisamos entender o que é hashing e para que serve. Hashing é um processo de aplicação de uma função de hash a alguns dados. Uma função hash é apenas uma função matemática. Não se preocupe com isso! “Matemático” nem sempre significa “complicado”. Aqui significa apenas que temos alguns dados e uma certa regra que mapeia os dados em um conjunto de caracteres (código). Por exemplo, pode ser uma cifra hexadecimal. Temos alguns dados de qualquer tamanho na entrada e aplicamos uma função hash a eles. Na saída, obtemos dados de tamanho fixo, digamos, 32 caracteres. Normalmente, esse tipo de função converte um grande pedaço de dados em um pequeno valor inteiro. O resultado desse trabalho de função é chamado de código hash. As funções de hash são amplamente usadas em criptografia e em algumas outras áreas também. As funções hash podem ser diferentes,
Um determinado objeto tem um determinado hashcode.
Se dois objetos são iguais, seus hashcodes são os mesmos. O contrário não é verdade.
Se os códigos hash forem diferentes, os objetos não são iguais com certeza.
Objetos diferentes podem ter o mesmo código hash. No entanto, é um evento muito improvável. Nesse ponto, temos uma colisão, uma situação em que podemos perder dados.
A função hash "adequada" minimiza a probabilidade de colisões.
Código Hash em Java
Em Java, a função hash geralmente é conectada ao método hashCode() . Precisamente, o resultado da aplicação de uma função hash a um objeto é um código hash. Todo objeto Java possui um código hash. Em geral, o Código Hash é um número calculado pelo método hashCode() da Objectclasse. Normalmente, os programadores substituem esse método para seus objetos, bem como relacionados a hashCode() o método equals() para processamento mais eficiente de dados específicos. O método hashCode() retorna um valor int (4 bytes), que é uma representação numérica do objeto. Esse hashcode é usado, por exemplo, por coleções para armazenamento mais eficiente de dados e, consequentemente, acesso mais rápido a eles. Por padrão, o hashCode()função para um objeto retorna o número da célula de memória onde o objeto está armazenado. Portanto, se nenhuma alteração for feita no código do aplicativo, a função deverá retornar o mesmo valor. Se o código mudar ligeiramente, o valor hashcode também mudará. Para que serve o hashcode em Java? Em primeiro lugar, os hashcodes Java ajudam os programas a serem executados mais rapidamente. Por exemplo, se compararmos dois objetos o1e o2de algum tipo, a operação o1.equals(o2)leva cerca de 20 vezes mais tempo do que o1.hashCode() == o2.hashCode().
Java é igual a()
Na classe pai Object, junto com o método hashCode() , também existe equals() , a função que é usada para verificar a igualdade de dois objetos. A implementação padrão dessa função simplesmente verifica os links de dois objetos quanto à sua equivalência. equals() e hashCode() têm seu contrato, portanto, se você substituir um deles, deverá substituir o outro, para não quebrar este contrato.
Implementando o método hashCode()
Exemplo
Vamos criar uma classe Character com um campo — name . Depois disso, criamos dois objetos da classe Character , character1 e character2 e os definimos com o mesmo nome. Se usarmos o padrão hashCode() e equals() da classe Object , definitivamente obteremos objetos diferentes, não iguais. É assim que funciona o hashcode em Java. Eles terão hashcodes diferentes porque estão em células de memória diferentes e o resultado da operação equals() será falso.
Dois números de 10 dígitos no console são códigos hash. E se quisermos ter objetos iguais se eles tiverem os mesmos nomes? O que deveríamos fazer? A resposta: devemos sobrescrever os métodos hashCode() e equals() da classe Object para nossa classe Character . Poderíamos fazer isso automaticamente no IDEA IDE, basta pressionar alt + insert no teclado e escolher Generate -> equals() e hashCode() . No caso do nosso exemplo temos o seguinte código:
Então agora o programa identifica nossos objetos como iguais e eles têm os mesmos hashcodes.
Exemplo de hashcode Java:
Seu próprio hashCode() e equals()
Você também pode criar suas próprias realizações equals() e hashCode() , mas tenha cuidado e lembre-se de minimizar as colisões de hashcode. Aqui está um exemplo de nossos próprios métodos hashCode() e equals() na classe Aluno :
importjava.util.Date;publicclassStudent{String surname;String name;String secondName;Long birthday;// Long instead of long is used by Gson/Jackson json parsers and various orm databasespublicStudent(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@OverridepublicinthashCode(){//TODO: check for nulls//return surname.hashCode() ^ name.hashCode() ^ secondName.hashCode() ^ (birthday.hashCode());return(surname + name + secondName + birthday).hashCode();}@Overridepublicbooleanequals(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));}}
E a classe Main para demonstrar seu trabalho:
importjava.util.Date;importjava.util.HashMap;importjava.util.Hashtable;publicclassMain{staticHashMap<Student,Integer> cache =newHashMap<Student,Integer>();// <person, targetPriority>publicstaticvoidmain(String[] args){Student sarah1 =newStudent("Sarah","Connor","Jane",null);Student sarah2 =newStudent("Sarah","Connor","Jane",newDate(1970,01-1,01));Student sarah3 =newStudent("Sarah","Connor","Jane",newDate(1959,02-1,28));// date not existsStudent john =newStudent("John","Connor","Kyle",newDate(1985,02-1,28));// date not existsStudent johnny =newStudent("John","Connor","Kyle",newDate(1985,02-1,28));// date not existsSystem.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(newDate(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));}}
Para que serve o código hash?
Em primeiro lugar, os códigos hash ajudam os programas a serem executados mais rapidamente. Por exemplo, se compararmos dois objetos o1e o2de algum tipo, a operação o1.equals(o2)leva cerca de 20 vezes mais tempo do que o1.hashCode() == o2.hashCode(). Em Java, o princípio de hash está por trás de algumas coleções populares, como HashMap , HashSet e HashTable .
Conclusão
Todo objeto Java possui os métodos hashCode() e equals() herdados da classe Object . Para obter um bom mecanismo de igualdade de trabalho, é melhor sobrescrever os métodos hashcode() e equals() para suas próprias classes. O uso de hashcodes torna os programas mais rápidos.