The answer to this question is to use a custom class as the key, so you have to override equals() and hashCode().

The Object API explains the equal and hashCode methods:

  • Equal (identical) objects must have equal hash (or hash) codes
  • Both objects have the same hashCode; they don’t have to be the same

For example:

Equal (identical) objects must have equal hash (or hash) codes

Imagine two Java objects A and B, A and B are equal (eQAuls is true), but A and B have different hash codes. If A and B are stored in A HashMap, the hash codes calculated by A and B may have different indexes of the internal array positions of the HashMap. Then A and B are likely to allow both objects to be stored in A HashMap. Obviously equal/identical elements are not allowed to be stored in a HashMap at the same time, and a HashMap is not allowed to store duplicate elements.

Both objects have the same hashCode; they don’t have to be the same

That is, different objects may have the same hashCode; If two Java objects A and B, A and B are not equal (eQAuls result is false), but the hash codes of A and B are equal, A hash collision will occur when both A and B are stored in the HashMap. That is, the HashMap will create A linked table at that position. String A and B together in this position, which is clearly permissible without violating the HashMap usage rules. Of course, as few hash collisions as possible, try to use a good hash algorithm to avoid hash collisions.

Hashset inherits the Set interface, which implements the Collection interface, which is hierarchical. How do the storage operations in Hashset, Hashmap, and Hashtable access objects?

Using a HashSet as an example, we all know that no duplicate objects are allowed in a HashSet, and the positions of elements are indeterminate. How do you determine whether elements are repeated in a hashset? In Java collections, the rule for determining whether two objects are equal is:

  1. Determine whether the hashcodes of the two objects are equal. If they are not equal, the two objects are considered not equal, end. If it is the same, turn it over to 2 (this point is only required to improve storage efficiency, in fact, in theory, it can not, but if it is not, the efficiency will be greatly reduced in practice, so we will use it as a necessary.)

  2. Determine whether two objects are equal using equals, and if they are not, consider them not equal. If they are equal, consider two objects equal. (Equals () is the key to determining whether two objects are equal.)

Why two rules? Can’t we just use the first one? No, because, as mentioned earlier, hashcode() is equal and equals() may not be equal, so the second rule must be applied to ensure that non-repeating elements are added.

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

class Person {
    String id;
    String name;
    public Person(String id, String name) {
        this.id = id;
        this.name = name;
    }
    public String toString(a) {
        return "id = " + id + " , name = "+ name; }}class Student {
    String id;
    String name;
    public Student(String id, String name) {
        this.id = id;
        this.name = name;
    }
    public int hashCode(a) {
        return id.hashCode();
    }
    public boolean equals(Object ob) {
        Student student = (Student)ob;
        if(student.id.equals(this.id)) {
            return true;
        }else {
            return false; }}public String toString(a) {
        return "id = " + id + " , name = "+ name; }}public class HashCodeTest {

    public static void main(String[] args) {
        testStringHash();
        testHashSetWithoutEquals();
        testHashSetWithEquals();
    }
    // The test does not implement equals and hashCode
    public static void testHashSetWithoutEquals(a) {
        Set<Person> personSet = new HashSet<Person>();
        personSet.add(new Person("123"."Tom"));
        personSet.add(new Person("123"."Tom"));
        Iterator<Person> iterator = personSet.iterator();
        while(iterator.hasNext()) { Person person = iterator.next(); System.out.println(person.toString()); }}// The test implements equals and hashCode
    public static void testHashSetWithEquals(a) {
        Set<Student> studentSet = new HashSet<Student>();
        studentSet.add(new Student("123"."Tom"));
        studentSet.add(new Student("123"."Tom"));
        Iterator<Student> iterator = studentSet.iterator();
        System.out.println("* * * * * * * * * * * * * * * * * * * *");
        while(iterator.hasNext()) { Student student = iterator.next(); System.out.println(student.toString()); }}The String class overrides the EQUALS and hashCode reference JDK implementations
    public static void testStringHash(a) {
        Object a = new Object();
        String s1 = new String("abc");
        String s2 = new String("abc");
        System.out.println(s1 == s2);
        System.out.println(s1.equals(s2));
        System.out.println("hashCode s1 = " + s1.hashCode());
        System.out.println("hashCode s2 = " + s2.hashCode());
        Set hashSet = new HashSet<String>();
        hashSet.add(s1);
        hashSet.add(s2);
        Iterator it = hashSet.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
        System.out.println("* * * * * * * * * * * * * * * * * * *"); }}Copy the code

Similarly, the tests for hashMap are as follows

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

class Person {
    String id;
    String name;
    public Person(String id, String name) {
        this.id = id;
        this.name = name;
    }
    public String toString(a) {
        return "id = " + id + " , name = "+ name; }}class Student {
    String id;
    String name;
    public Student(String id, String name) {
        this.id = id;
        this.name = name;
    }
    public int hashCode(a) {
        return id.hashCode();
    }
    public boolean equals(Object ob) {
        Student student = (Student)ob;
        if(student.id.equals(this.id)) {
            return true;
        }else {
            return false; }}public String toString(a) {
        return "id = " + id + " , name = "+ name; }}public class HashMapTest {
    public static void main(String[] args) {
       testHashMapWithoutEquals();
       testHashMapWithEquals();
    }
    public static void testHashMapWithoutEquals(a) {
        Map<Person, String> hMap = new HashMap<Person, String>();
        Person person1 = new Person("123"."Tom");
        Person person2 = new Person("123"."Tom");
        hMap.put(person1, "address");
        hMap.put(person2, "address");
        Iterator iterator = hMap.entrySet().iterator();
        while(iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            Person key = (Person) entry.getKey();
            String val = (String) entry.getValue();
            System.out.println("key = " + key + " value = "+ val); }}public static void testHashMapWithEquals(a) {
        System.out.println("* * * * * * * * * * * * * * * * * * * * *");
        Map<Student, String> hMap = new HashMap<Student, String>();
        Student student1 = new Student("123"."Tom");
        Student student2 = new Student("123"."Tom");
        hMap.put(student1, "address");
        hMap.put(student2, "address");
        Iterator iterator = hMap.entrySet().iterator();
        while(iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            Student key = (Student) entry.getKey();
            String val = (String) entry.getValue();
            System.out.println("key = " + key + " value = "+ val); }}}Copy the code

Related articles

  1. www.cnblogs.com/Qian123/p/5…