Comprensión simple de varios métodos de reescritura de HashSet y HashTree en la colección

El conjunto en Java no está ordenado, pero no es repetible. La
capa inferior de HashSet es una tabla hash. La deduplicación se logra llamando a los métodos hashcode y equals.
Cuando hay cadenas en nuestro HashSet, podemos deduplicar por defecto, porque String Ha reescrito los métodos hashcode y euqals.

    public static void main(String[] args) {
        HashSet<String> set = new HashSet();
        set.add("java");
        set.add("c");
        set.add("php");
        set.add("bigdata");
        set.add("java");
        //运行结果,给去重了,而且是无序的
        System.out.println(set);//[java, c, bigdata, php]
    }
}

Pero cuando tenemos clases, como Persona, Gato, Perro, clases que escribimos nosotros mismos, pero queremos reiterarlas de acuerdo con nuestras propias reglas, como el nombre y la edad de la Persona, porque la clase Persona la construimos nosotros mismos, si No tenemos que reescribir el método, buscaremos el método hashcode de Object, para que el hashcode de new Person () sea diferente, de modo que cada uno sea nuevo y saldrá, incluso si la edad y el nombre son iguales

public class Demo1 {
    
    
    public static void main(String[] args) {
    
    
        HashSet<Person> set1 = new HashSet<>();
        set1.add(new Person("aing",50));
        set1.add(new Person("bing",10));
        set1.add(new Person("ding",20));
        set1.add(new Person("ding",20));
        //运行结果是即使名字年龄一样,也会输出两个,我们如果想要按照自己的规则去重,这样我们一定要重写hashcode 和euqals方法
        System.out.println(set1);//[Person{name='bing', age=10}, Person{name='ding', age=20}, Person{name='aing', age=50}, Person{name='ding', age=20}]
    }
}
class Person{
    
    
    String name;
    int age;

    public Person(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Reescribimos el método hashcode. Cuando el hashcode es diferente, no comparará iguales, pero será diferente. Si el hashcode es el mismo, compare el método equals.

public class Demo1 {
    
    
    public static void main(String[] args) {
    
    
        HashSet<Person> set1 = new HashSet<>();
        set1.add(new Person("aing",50));
        set1.add(new Person("bing",10));
        set1.add(new Person("ding",20));
        set1.add(new Person("ding",20));
        //根据年龄和姓名比较的
        System.out.println(set1);//[Person{name='ding', age=20}, Person{name='aing', age=50}, Person{name='bing', age=10}]
    }
}
class Person{
    
    
    String name;
    int age;
    public Person(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
    
    
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    @Override
    public boolean equals(Object o) {
    
    
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }
    //和属性关联,根据属性的值比较,之所以让age*100;是因为怕有可能出现这个name.hashCode()+age 和 下一个name.hashCode()+age加起来的值恰好相等,所以age*100,可以避免这种情况的发生
    @Override
    public int hashCode() {
    
    
        //return Objects.hash(name, age);
        return name.hashCode()+age*100;
    }
}

La capa inferior del TreeSet es un árbol binario, y el TreeSet todavía está en orden. No solo se llama al código hash en el String, sino que también se llama al método compareTo del elemento, la clase String ha implementado la interfaz Comparable y ha reescrito el método compareTo, pero si escribimos nuestra propia clase Por ejemplo, si desea comparar de acuerdo con sus propias reglas, debe reescribir el método hashcode e implementar la interfaz Comparable

public class Demo2 {
    
    
    public static void main(String[] args) {
    
    
        TreeSet<String> set = new TreeSet();
        set.add("java");
        set.add("c");
        set.add("php");
        set.add("bigdata");
        set.add("java");
        System.out.println(set);//[bigdata, c, java, php]
    }
}

Pero si su propia clase
informa del error "no se puede convertir a java.lang.Comparable", porque Person buscará el método compareTo, pero la clase Person no lo implementa, tenemos que implementar Comparable

public class Demo2 {
    
    
    public static void main(String[] args) {
    
    
        TreeSet<Person1> set1 = new TreeSet<>();
        set1.add(new Person1("aing",50));
        set1.add(new Person1("bing",10));
        set1.add(new Person1("ding",20));
        set1.add(new Person1("ding",20));
        System.out.println(set1);
    }
}
class Person1{
    
    
    String name;
    int age;

    public Person1(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Person1{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Para que podamos lograr el orden, según nuestros atributos.

public class Demo2 {
    
    
    public static void main(String[] args) {
    
    
        TreeSet<Person1> set1 = new TreeSet<>();
        set1.add(new Person1("aing",50));
        set1.add(new Person1("bing",10));
        set1.add(new Person1("ding",20));
        set1.add(new Person1("ding",20));
        System.out.println(set1);
    }
}
class Person1 implements Comparable{
    
    
    String name;
    int age;

    public Person1(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
    
    
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person1 person1 = (Person1) o;
        return age == person1.age &&
                Objects.equals(name, person1.name);
    }

    @Override
    public int hashCode() {
    
    
        return name.hashCode()+age*100;
    }

    @Override
    public String toString() {
    
    
        return "Person1{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    //根据类的属性进行排序
    @Override
    public int compareTo(Object o) {
    
    
    Person1 person = (Person1)o;
    int num = name.compareTo(person.name);
    return num==0?age-person.age:num;
}
}

Supongo que te gusta

Origin blog.csdn.net/m0_51327764/article/details/109018469
Recomendado
Clasificación