欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

TreeSet/map的去重和排序

程序员文章站 2022-05-14 13:08:12
...

TreeSet/map的去重和排序

TreeSet集合

TreeSet集合是可以给元素进行重新排序的一个Set接口的实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的Comparator进行排序,具体取决于使用的构造方法。

存储特点:
无序存储,排重,通过红黑树实现的集合,可以给元素进行重新排序

我们知道Set集合中的元素都是无序不重复的,而TreeSet中的元素却是有序(这里的有序是按照字典顺序排列,基本数据类型和String的话字母按照a-z,数字按照大小)不重复的,所以在保存没有实现排序功能的**对象(注意是对象类型)**时,他不知道应该怎么进行进行排序,直接往TreeSet集合中添加没有实现Compareable或者没有传入构造器时就会报错:

Exception in thread “main” java.lang.ClassCastException: Student cannot be castto java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1188)
at java.util.TreeMap.put(TreeMap.java:531)
at java.util.TreeSet.add(TreeSet.java:255)
at TreeSetOrderDemo.main(TreeSetOrderDemo.java:18) 

我们在使用TreeSet集合时候必须要实现Compareable接口来实现排序,实现排序有两种方式。

第一种排序方式:对象类中实现Compareable接口并重写其方法:

package set;

public class Student implements Comparable<Student>{
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public int compareTo(Student o) {
        int n1=this.name.compareTo(o.name);
        int n2=this.age-o.age;
        return n1==0?n2:n1;
    }


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

  /*  @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
*/
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

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

这里Student类中实现了Compable接口并重写了其方法,按照自定义的规则来排序,同时还具有去重的功能:
` public int compareTo(Student o) {

    int n1=this.name.compareTo(o.name);
    int n2=this.age-o.age;
    return n1==0?n2:n1;
}

这里按先按姓名的默认来排序,姓名相同的话按照年龄的升序排序,两者都为0的话就是重复元素,则不添加。年龄降序的话反过来就行,其中返回值等于0证明元素属性相同,大于0放到二叉树右边,小于0 放二叉树左边然后根据二叉树的排序进行取出达到排序去重目的。

第二种实现方式

元素需要通过java.util.Comparator接口(比较器)中的compare方法进行比较大小,并排序。
compare方法除了可以进行排序外,还有排重的功能,但是必须在compare方法中对类中所有的属性值都进行判断,否则不比较那个属性,排重就会忽略哪个属性
TreeSet集合中的无参数构造方法默认使用自然排序的方式对元素进行排序,使用TreeSet集合的定制排序时,创建集合对象不可以直接使用无参数构造方法,需要使用传入一个Comparator比较器的构造方法创建集合对象。
也可以定义一个Comparator接口的,新建一个实现类,作为参数传递到集合的构造中
代码块如下( MyComparator()是Comparator和接口实现类):

Comparator实现类作为参数传入

package set;

import java.util.Comparator;

public class MyComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        int n1= o1.getName().compareTo(o2.getName());
        int n2=o1.getAge()-o2.getAge();
        return n2==0?n1:n2;
    }
}

package set;
import java.util.TreeSet;
public class TreeSetDemo2 {
    public static void main(String[] args) {
        /*两种方式实现treeset插入排序
        1.在元素类中实现Comparable<Student>接口
        2.自定义比较器  实现Comparator<Student>接口  在创建集合的时候  声明一下
        * */
        TreeSet<Student> treeSet1=new TreeSet<>(new MyComparator());//无序的  但是可以根据字典顺序进行排序
        treeSet1.add(new Student("jack",23));
        treeSet1.add(new Student("rose",24));
        treeSet1.add(new Student("mike",25));
        treeSet1.add(new Student("lily",26));
        treeSet1.add(new Student("jack",24));
        System.out.println("元素个数:"+treeSet1.size());
        System.out.println(treeSet1);
    }
}

直接传入匿名对象 Comparator重写排序方法

 TreeSet<Student> treeSet2=new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int n1= o1.getName().compareTo(o2.getName());
                int n2=o1.getAge()-o2.getAge();
                return n2==0?n1:n2;
            }
        });//无序的  但是可以根据字典顺序进行排序
        treeSet1.add(new Student("jack",23));
        treeSet1.add(new Student("rose",24));
        treeSet1.add(new Student("mike",25));
        treeSet1.add(new Student("lily",26));
        treeSet1.add(new Student("jack",24));
        System.out.println("元素个数:"+treeSet1.size());
        System.out.println(treeSet1);
    }

这样就是Comparator的两种是排序实现,TreeSet和HashSet的排序去重实现是一致的,只不过HashSet排序的是键,而treeSet排序的是元素本身。

相关标签: TreeSet