TreeSet/map的去重和排序
发布日期:2022-02-01 14:28:20 浏览次数:43 分类:技术文章

本文共 4250 字,大约阅读时间需要 14 分钟。

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.Comparableat 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
{ 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
{ @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
接口 2.自定义比较器 实现Comparator
接口 在创建集合的时候 声明一下 * */ TreeSet
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
treeSet2=new TreeSet<>(new Comparator
() { @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排序的是元素本身。

转载地址:https://blog.csdn.net/shunshizhen120412/article/details/98851433 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:HashSet的去重
下一篇:InputStreamReader和OutputStreamWriter 的区别和用法简介

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年04月08日 20时01分14秒