Compreensão simples de vários métodos de reescrita de HashSet e HashTree na coleção

O conjunto em Java não está ordenado, mas não pode ser repetido. A
camada inferior do HashSet é uma tabela de hash. A desduplicação é obtida chamando os métodos hashcode e equals.
Quando há strings em nosso HashSet, podemos desduplicar por padrão, porque String Reescreveu os métodos hashcode e 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]
    }
}

Mas quando temos classes, como Person, Cat, Dog, classes que escrevemos nós mesmos, mas queremos reiterá-las de acordo com nossas próprias regras, como o nome de Person e idade, porque a classe Person é construída por nós mesmos, se Não temos que reescrever o método, vamos procurar o método hashcode de Object, para que o hashcode de new Person () seja diferente, de forma que cada um seja um novo e seja gerado, mesmo que a idade e o nome sejam os mesmos

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 +
                '}';
    }
}

Reescrevemos o método do hashcode. Quando o hashcode for diferente, ele não irá comparar equals, mas será diferente. Se o hashcode for o mesmo, compare o 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;
    }
}

A camada inferior do TreeSet é uma árvore binária, e o TreeSet ainda está em ordem. Não apenas o hashcode na String, mas também o método compareTo do elemento é chamado, a classe String implementou a interface Comparable e reescreveu o método compareTo, mas se escrevermos o nosso próprio Por exemplo, se você deseja comparar de acordo com suas próprias regras, você deve reescrever o método hashcode e implementar a interface 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]
    }
}

Mas se sua própria classe
reportar o erro “não pode ser convertido para java.lang.Comparable”, porque Person irá procurar pelo método compareTo, mas a classe Person não o implementa, temos 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 +
                '}';
    }
}

Assim, podemos alcançar a ordem, de acordo com nossos 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;
}
}

Acho que você gosta

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