CodeGym /Java Blog /Random-IT /Codice hash Java()
John Squirrels
Livello 41
San Francisco

Codice hash Java()

Pubblicato nel gruppo Random-IT

Principio hash

Prima di tutto, prima di definire l'hashcode Java, dobbiamo capire cos'è l'hashing ea cosa serve. L'hashing è un processo di applicazione di una funzione hash ad alcuni dati. Una funzione hash è solo una funzione matematica. Non preoccuparti di questo! “Matematico” non significa sempre “complicato”. Qui significa solo che abbiamo alcuni dati e una certa regola che mappa i dati in un insieme di caratteri (codice). Ad esempio, potrebbe essere un cifrario esadecimale. Abbiamo alcuni dati di qualsiasi dimensione in input e vi applichiamo una funzione hash. All'output, otteniamo dati di dimensioni fisse, diciamo, 32 caratteri. Di solito, questo tipo di funzione converte una grande quantità di dati in un piccolo valore intero. Il risultato di questo lavoro di funzione è chiamato codice hash. Le funzioni hash sono ampiamente utilizzate nella crittografia e anche in altre aree. Le funzioni hash possono essere diverse,
  • Un particolare oggetto ha un particolare hashcode.
  • Se due oggetti sono uguali, i loro codici hash sono gli stessi. Non è vero il contrario.
  • Se i codici hash sono diversi, gli oggetti non sono sicuramente uguali.
  • Oggetti diversi possono avere lo stesso codice hash. Tuttavia, è un evento molto improbabile. A questo punto, abbiamo una collisione, una situazione in cui possiamo perdere dati.
La funzione hash "corretta" riduce al minimo la probabilità di collisioni.

Codice hash in Java

In Java la funzione hash è solitamente collegata al metodo hashCode() . Precisamente, il risultato dell'applicazione di una funzione hash a un oggetto è un codice hash. Ogni oggetto Java ha un codice hash. In generale Hash Code è un numero calcolato dal metodo hashCode() della Objectclasse. Di solito, i programmatori sovrascrivono questo metodo per i loro oggetti e, in relazione a hashCode() , il metodo equals() per un'elaborazione più efficiente di dati specifici. Il metodo hashCode() restituisce un valore int (4 byte), che è una rappresentazione numerica dell'oggetto. Questo hashcode viene utilizzato, ad esempio, dalle raccolte per un'archiviazione più efficiente dei dati e, di conseguenza, un accesso più rapido ad essi. Per impostazione predefinita, hashCode()funzione per un oggetto restituisce il numero della cella di memoria in cui è memorizzato l'oggetto. Pertanto, se non vengono apportate modifiche al codice dell'applicazione, la funzione dovrebbe restituire lo stesso valore. Se il codice cambia leggermente, cambia anche il valore hashcode. A cosa serve l'hashcode in Java? Prima di tutto gli hashcode Java aiutano i programmi a funzionare più velocemente. Ad esempio, se confrontiamo due oggetti o1e o2di qualche tipo, l'operazione o1.equals(o2)richiede circa 20 volte più tempo di o1.hashCode() == o2.hashCode().

Java è uguale a()

Nella classe genitore Object, insieme al metodo hashCode() , c'è anche equals() , la funzione che serve per verificare l'uguaglianza di due oggetti. L'implementazione predefinita di questa funzione controlla semplicemente i collegamenti di due oggetti per verificarne l'equivalenza. equals() e hashCode() hanno il loro contratto, quindi se ne sovrascrivi uno, dovresti sovrascrivere l'altro, per non rompere questo contratto.

Implementazione del metodo hashCode()

Esempio

Creiamo una classe Character con un campo — name . Successivamente, creiamo due oggetti della classe Character , character1 e character2 e impostiamo loro lo stesso nome. Se usiamo hashCode() e equals() predefiniti della classe Object , otterremo sicuramente oggetti diversi, non uguali. Ecco come funziona l'hashcode in Java. Avranno codici hash diversi perché si trovano in celle di memoria diverse e il risultato dell'operazione equals() sarà falso.

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));
    }
}
Il risultato dell'esecuzione del programma:

Arnold
1595428806
Arnold
1072408673
false
Due numeri di 10 cifre nella console sono codici hash. E se volessimo avere oggetti uguali se hanno gli stessi nomi? Cosa dovremmo fare? La risposta: dovremmo ignorare i metodi hashCode() e equals() della classe Object per la nostra classe Character . Potremmo farlo automaticamente in IDEA IDE, basta premere alt + insert sulla tastiera e scegliere Generate -> equals() e hashCode() . Cos'è Java hashCode() - 2Nel caso del nostro esempio abbiamo il seguente codice:

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));
    }
}
Il risultato dell'esecuzione di questo codice:

Arnold
1969563338
Arnold
1969563338
true
Quindi ora il programma identifica i nostri oggetti come uguali e hanno gli stessi hashcode.

Esempio di codice hash Java:

Il tuo hashCode() e equals()

Puoi anche creare le tue realizzazioni equals() e hashCode() , ma fai attenzione e ricorda di ridurre al minimo le collisioni hashcode. Ecco un esempio dei nostri metodi hashCode() e equals() nella classe Student :

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));
   }
}
E la classe principale per dimostrare il loro lavoro:

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));
   }
}

A cosa serve l'hashcode?

Prima di tutto gli hashcode aiutano i programmi a funzionare più velocemente. Ad esempio, se confrontiamo due oggetti o1e o2di qualche tipo, l'operazione o1.equals(o2)richiede circa 20 volte più tempo di o1.hashCode() == o2.hashCode(). In Java il principio dell'hashing è alla base di alcune raccolte popolari, come HashMap , HashSet e HashTable .

Conclusione

Ogni oggetto Java ha i metodi hashCode() e equals() ereditati dalla classe Object . Per ottenere un buon meccanismo di uguaglianza funzionante, è meglio sovrascrivere i metodi hashcode() e equals() per le proprie classi. L'uso di codici hash rende i programmi più veloci.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION