龙岗区建设规划网站,运营电商,企业网站托管多少钱,怎样做网站权重TreeSet 集合 1. 概述2. 方法3. 遍历方式4. 两种排序方式4.1 默认排序规则/自然排序4.1.1 概述4.1.2 compareTo()方法4.1.3 代码示例14.1.4 代码示例2 4.2 比较器排序4.2.1 概述4.2.2 compare()方法4.2.3 代码示例14.2.4 代码示例2 4.3 排序方式的对比 5. 注意事项 文章中的部分… TreeSet 集合 1. 概述2. 方法3. 遍历方式4. 两种排序方式4.1 默认排序规则/自然排序4.1.1 概述4.1.2 compareTo()方法4.1.3 代码示例14.1.4 代码示例2 4.2 比较器排序4.2.1 概述4.2.2 compare()方法4.2.3 代码示例14.2.4 代码示例2 4.3 排序方式的对比 5. 注意事项 文章中的部分照片来源于哔站黑马程序员阿伟老师处仅用学习无商用侵权联系删除 其他集合类 祖父类 Collection 父类 Set 集合类的遍历方式 具体信息请查看 API 帮助文档 1. 概述
TreeSet是Java中的一个有序集合它实现了Set接口。它使用红黑树数据结构来存储元素并且保证元素按照升序排列。每个元素都必须是可比较的或者在创建TreeSet时提供一个定制的Comparator来比较元素。
TreeSet集合(底层是红黑树) 不重复无索引可排序 可排序按照元素的默认规则由小到大进行排序 TreeSet集合底层是基于红黑树的数据结构实现排序的增删改查性能都较好
TreeSet的特点 有序性TreeSet中的元素按照升序排列默认使用元素自然顺序进行比较或者可以通过提供一个Comparator来指定定制的排序规则。 无重复性TreeSet不允许存储重复的元素。如果尝试添加重复的元素添加操作会被忽略。 高效性由于采用了红黑树数据结构TreeSet支持快速的插入、删除和查找操作时间复杂度为O(logN)。
2. 方法 TreeSet集合是Set集合的子类是Collection集合的孙子类因此Set集合和Collection集合的方法都可以使用 Collection集合 Set集合 方法名说明boolean add(E e)添加元素boolean remove(Object o)从集合中移除指定的元素boolean removeIf(Object o)根据条件进行移除void clear()清空集合中的元素boolean contains(Object o)判断集合中是否存在指定的元素boolean isEmpty()判断集合是否为空int size()集合的长度也就是集合中元素的个数
3. 遍历方式
【注意】TreeSet集合没有索引因此只能用迭代器遍历、增强 for Lambda表达式遍历。 与共有的 集合遍历方式 一样 代码示例
package text.text02;import java.util.Iterator;
import java.util.TreeSet;/*
TreeSet集合(底层是红黑树)1.不重复无索引可排序2.可排序按照元素的默认规则由小到大进行排序3.TreeSet集合底层是基于红黑树的数据结构实现排序的增删改查性能都较好需求存储整数并进行排序*/
public class text40 {public static void main(String[] args) {//创建集合并添加数据TreeSetInteger ts new TreeSet();ts.add(4);ts.add(7);ts.add(6);ts.add(3);ts.add(1);ts.add(5);ts.add(2);ts.add(8);ts.add(9);//打印集合System.out.println(ts); //[1, 2, 3, 4, 5, 6, 7, 8, 9]//遍历集合IteratorInteger it ts.iterator();while (it.hasNext()) {Integer i it.next();System.out.print(i ); //1 2 3 4 5 6 7 8 9}}
}
输出结果
4. 两种排序方式 方法一默认排序规则/自然排序 JavaBean类实现Comparable接口指定比较规则重写里面的抽象方法再比较 方法二比较器排序 创建TreeSet对象时候自定义比较器Comparator对象指定比较规则
4.1 默认排序规则/自然排序
4.1.1 概述
默认排序规则也称为自然排序是指针对某种数据类型的元素按照它们的自身特性进行排序的规则。在Java中如果一个类实现了Comparable接口就意味着它具有自然顺序并且可以使用默认排序规则。
在使用默认排序规则进行排序时会根据元素的特定属性或者重写的compareTo()方法来进行比较。默认情况下元素按照升序排列也就是具有较小值的元素在集合中排在前面。 例如对于整数类型自然排序规则就是按照数值大小进行排序。而对于字符串类型自然排序规则是按照字典顺序进行排序。 以下是一些实现了Comparable接口的示例类及其默认排序规则
Integer类按数值大小进行升序排序。String类按字典顺序进行排序。LocalDate类按日期进行升序排序。自定义类可以通过实现Comparable接口并重写compareTo()方法来定义自己的默认排序规则。
注意如果你想使用不同于默认排序规则的排序方式可以通过提供一个定制的Comparator来实现定制排序。
默认排序示意图
4.1.2 compareTo()方法
compareTo()方法是Comparable接口中定义的方法用于比较当前对象与另一个对象的顺序。它的方法签名如下
int compareTo(T obj)其中T表示要比较的对象的类型。compareTo()方法接受一个参数obj表示要与当前对象进行比较的另一个对象返回一个整数值表示它们的顺序关系。 this: 要添加的元素(当前对象 obj红黑树中已经存在的数据 compareTo()方法返回的整数值有以下三种情况 当compare()方法返回一个负数时表示第一个元素应排在前面 当返回0时表示两个元素相等 当返回一个正数时表示第一个元素应排在后面。
具体返回的值大小并不重要只有它们的正负号和零的关系才有意义。返回的值为负当前对象就应该排在obj之前返回的值为正当前对象就应该排在obj之后。
4.1.3 代码示例1
代码示例
需求创建TreeSet集合并添加3个学生对象 学生对象属性姓名、年龄 要求按照学生的年龄进行排序同年龄按照姓名字母排列暂不考虑中文同姓名、同年龄认为是同一个人
package text.text02;import java.util.Iterator;
import java.util.TreeSet;/* 方法一默认排序规则/自然排序方法一默认排序规则/自然排序JavaBean类实现Comparable接口指定比较规则重写里面的抽象方法再比较
方法二比较器排序创建TreeSet对象时候传递比较器Comparator指定规则TreeSet对象排序练习题
需求创建TreeSet集合并添加3个学生对象
学生对象属性姓名、年龄
要求按照学生的年龄进行排序同年龄按照姓名字母排列暂不考虑中文同姓名、同年龄认为是同一个人*/
public class text41 {public static void main(String[] args) {//创建学生对象Student4 student1 new Student4(zhangsan, 13);Student4 student2 new Student4(llisi, 25);Student4 student3 new Student4(wangwu, 12);Student4 student4 new Student4(zhaoliu, 20);Student4 student5 new Student4(liuqi, 11);//创建集合并添加元素TreeSetStudent4 ts new TreeSet();ts.add(student1);ts.add(student2);ts.add(student3);ts.add(student4);ts.add(student5);//遍历集合IteratorStudent4 it ts.iterator();while (it.hasNext()) {Student4 student it.next();System.out.println(student.getName() , student.getAge());/*liuqi,11wangwu,12zhangsan,13zhaoliu,20llisi,25*/}}
}//重写CompareTo的实现了Comparable接口的学生类
class Student4 implements ComparableStudent4 {private String name;private int age;public Student4() {}public Student4(String name, int age) {this.name name;this.age age;}/*** 获取** return name*/public String getName() {return name;}/*** 设置** param name*/public void setName(String name) {this.name name;}/*** 获取** return age*/public int getAge() {return age;}/*** 设置** param age*/public void setAge(int age) {this.age age;}public String toString() {return Student4{name name , age age };}//重写抽象方法CompareTo方法Override//this:表示当前要添加的元素//o表示已经在红黑树中的元素//返回值//负数表示当前要添加的数据是小的存左边//正数表示当前要添加的数据是大的存右边//0表示当前要添加的元素已经存在舍弃public int compareTo(Student4 o) {System.out.println(---------------CompareTo方法-----------);System.out.println(this: this);System.out.println(o: o);System.out.println();//指定排序的规则//只看年龄按照年龄的升序进行排列return this.getAge() - o.getAge();}}输出结果
4.1.4 代码示例2
代码示例 需求创建5个学生对象 属性姓名、年龄语文成绩。数学成绩、英语成绩 要求按照总分从高到低输出到控制台 如果总分一样按照语文成绩排 如果语文一样按照数学成绩排 如果数学一样按照英语成绩排 如果英语一样按照年龄排 如果都一样认为是同一个学生不存
package text.text02;
/*
TreeSet对象排序练习题
需求创建5个学生对象
属性姓名、年龄语文成绩。数学成绩、英语成绩
要求按照总分从高到低输出到控制台如果总分一样按照语文成绩排如果语文一样按照数学成绩排如果数学一样按照英语成绩排如果英语一样按照年龄排如果都一样认为是同一个学生不存*///方法一默认排序规则/自然排序
// JavaBean类实现Comparable接口指定比较规则重写里面的抽象方法再比较import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;public class text43 {public static void main(String[] args) {//创建5个学生对象text.text02.Student6 student1 new text.text02.Student6(张三, 15, 99, 98, 90);text.text02.Student6 student2 new text.text02.Student6(李四, 14, 79, 56, 36);text.text02.Student6 student3 new text.text02.Student6(王五, 16, 95, 96, 85);text.text02.Student6 student4 new text.text02.Student6(赵六, 19, 93, 68, 83);text.text02.Student6 student5 new text.text02.Student6(刘备, 12, 75, 68, 73);//创建集合TreeSetStudent6 ts new TreeSet();//添加学生对象ts.add(student1);ts.add(student2);ts.add(student3);ts.add(student4);ts.add(student5);//遍历输出集合System.out.println(方法一默认排序规则/自然排序:);IteratorStudent6 it ts.iterator();while (it.hasNext()) {Student6 s it.next();int num s.getEnglish() s.getMath() s.getChinese();System.out.println(s.getName() , s.getAge() , s.getChinese() , s.getMath() , s.getEnglish() , num);}/*张三,15,99,98,90,287王五,16,95,96,85,276赵六,19,93,68,83,244刘备,12,75,68,73,216李四,14,79,56,36,171*/}
}class Student6 implements ComparableStudent6 {private String name;private int age;private int Chinese;private int Math;private int English;public Student6() {}public Student6(String name, int age, int Chinese, int Math, int English) {this.name name;this.age age;this.Chinese Chinese;this.Math Math;this.English English;}/*** 获取** return name*/public String getName() {return name;}/*** 设置** param name*/public void setName(String name) {this.name name;}/*** 获取** return age*/public int getAge() {return age;}/*** 设置** param age*/public void setAge(int age) {this.age age;}/*** 获取** return Chinese*/public int getChinese() {return Chinese;}/*** 设置** param Chinese*/public void setChinese(int Chinese) {this.Chinese Chinese;}/*** 获取** return Math*/public int getMath() {return Math;}/*** 设置** param Math*/public void setMath(int Math) {this.Math Math;}/*** 获取** return English*/public int getEnglish() {return English;}/*** 设置** param English*/public void setEnglish(int English) {this.English English;}public String toString() {return Student6{name name , age age , Chinese Chinese , Math Math , English English };}Override//this:要添加的数据//o红黑树中已经存在的数据public int compareTo(Student6 o) {//定义变量记录红黑树中已经存入的数据的成绩总和int sum o.getChinese() o.getMath() o.getEnglish();//定义变量记录要添加的数据的成绩总和int sum1 this.getChinese() this.getMath() this.getEnglish();//按照总分从高到低输出到控制台int i sum - sum1;//如果总分一样按照语文成绩排i i 0 ? o.getChinese() - this.getChinese() : i;//如果语文一样按照数学成绩排i i 0 ? o.getMath() - this.getMath() : i;//如果数学一样按照英语成绩排i i 0 ? o.getEnglish() - this.getEnglish() : i;//如果英语一样按照年龄排i i 0 ? o.getAge() - this.getAge() : i;//如果年龄一样按照姓名首字母排i i 0 ? o.getName().compareTo(this.getName()) : i;//返回值//负数表示当前要添加的数据是小的存左边//正数表示当前要添加的数据是大的存右边//0表示当前要添加的元素已经存在舍弃return i;}
}
输出结果
4.2 比较器排序
4.2.1 概述
比较器排序是一种在不修改元素的类定义或实现Comparable接口的情况下通过提供一个独立的比较器来排序元素的方法。
在Java中比较器Comparator是一个可以自定义排序规则的对象实现了Comparator接口。通过使用比较器可以按照自己定义的排序方式对元素进行排序而不依赖于元素自身的特性或默认的自然排序规则。
使用比较器进行排序的过程如下 创建一个实现了Comparator接口的比较器类其中包含compare()方法的实现。此方法定义了排序规则。 使用比较器对象创建一个集合如TreeSet、PriorityQueue等或者使用比较器作为参数调用排序方法如Arrays.sort()。 比较器会根据自定义的排序规则对集合中的元素进行排序。
4.2.2 compare()方法
比较器排序常用的方法是compare()方法该方法接受两个参数用于比较两个元素的顺序。 compare()方法是Comparator接口中定义的方法用于比较两个对象的顺序。它的方法签名如下
int compare(T obj1, T obj2)其中T表示要比较的对象的类型。compare()方法接受两个参数obj1和obj2分别表示要比较的两个对象返回一个整数值表示它们的顺序关系。 obj1:要添加的元素 obj2红黑树中已经存在的数据 compare()方法返回的整数值有以下三种情况 当compare()方法返回一个负数时表示第一个元素应排在前面 当返回0时表示两个元素相等 当返回一个正数时表示第一个元素应排在后面。 具体返回的值大小并不重要只有它们的正负号和零的关系才有意义。返回的值为负obj1就越应该排在obj2之前返回的值为正obj1就越应该排在obj2之后。 4.2.3 代码示例1
代码示例1 需求请自行选择比较器排序和自然排序两种方式 要求存入是个字符串 “c”,“ab”,“df”,“qwer”按照长度排序如果一样长则按照首字母进行排序
package text.text02;import java.util.Comparator;
import java.util.TreeSet;/* 方法二比较器排序方法一默认排序规则/自然排序JavaBean类实现Comparable接口指定比较规则重写里面的抽象方法再比较
方法二比较器排序创建TreeSet对象时候传递比较器Comparator指定规则TreeSet对象排序练习题需求请自行选择比较器排序和自然排序两种方式要求存入是个字符串 c,ab,df,qwer按照长度排序如果一样长则按照首字母进行排序*/
public class text42 {public static void main(String[] args) {//创建未排序的集合对象TreeSetString ts1 new TreeSet();//添加元素ts1.add(c);ts1.add(ab);ts1.add(df);ts1.add(qwer);//输出未排序的集合System.out.println(输出未排序的集合: ts1); //输出未排序得到集合:[ab, c, df, qwer]// 创建排序的集合对象// 创建TreeSet对象时候传递比较器Comparator指定规则//o1:表示当前要添加的元素//o2表示已经在红黑树存在的元素//返回值//负数表示当前要添加的数据是小的存左边//正数表示当前要添加的数据是大的存右边//0表示当前要添加的元素已经存在舍弃TreeSetString ts2 new TreeSet(new ComparatorString() {Overridepublic int compare(String o1, String o2) {//按照长度排序int i o1.length() - o2.length();//长度一样则按照首字母进行排序i i 0 ? o1.compareTo(o2) : i;return i;}});//添加元素ts2.add(c);ts2.add(ab);ts2.add(df);ts2.add(qwer);//输出排序的集合System.out.println(输出排序的集合: ts2); //输出排序的集合:[c, ab, df, qwer]}
}
输出结果 4.2.4 代码示例2
代码示例2 求创建5个学生对象 属性姓名、年龄语文成绩。数学成绩、英语成绩 要求按照总分从高到低输出到控制台 如果总分一样按照语文成绩排 如果语文一样按照数学成绩排 如果数学一样按照英语成绩排 如果英语一样按照年龄排 如果都一样认为是同一个学生不存
package text.text02;import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;/*
TreeSet对象排序练习题
需求创建5个学生对象
属性姓名、年龄语文成绩。数学成绩、英语成绩
要求按照总分从高到低输出到控制台如果总分一样按照语文成绩排如果语文一样按照数学成绩排如果数学一样按照英语成绩排如果英语一样按照年龄排如果都一样认为是同一个学生不存*///方法二比较器排序
// 创建TreeSet对象时候传递比较器Comparator指定规则public class text44 {public static void main(String[] args) {//创建5个学生对象Student5 student1 new Student5(张三, 15, 99, 98, 90);Student5 student2 new Student5(李四, 14, 79, 56, 36);Student5 student3 new Student5(王五, 16, 95, 96, 85);Student5 student4 new Student5(赵六, 19, 93, 68, 83);Student5 student5 new Student5(刘备, 12, 75, 68, 73);//创建集合TreeSetStudent5 ts new TreeSet(new ComparatorStudent5() {Override//o2:红黑树中已经存在的数据//o1:要添加的数据public int compare(Student5 o1, Student5 o2) {//定义变量记录红黑树中已经存入的数据的成绩总和int sum o2.getChinese() o2.getMath() o2.getEnglish();//定义变量记录要添加的数据的成绩总和int sum1 o1.getChinese() o1.getMath() o1.getEnglish();//按照总分从高到低输出到控制台int i sum - sum1;//如果总分一样按照语文成绩排i i 0 ? o2.getChinese() - o1.getChinese() : i;//如果语文一样按照数学成绩排i i 0 ? o2.getMath() - o1.getMath() : i;//如果数学一样按照英语成绩排i i 0 ? o2.getEnglish() - o1.getEnglish() : i;//如果英语一样按照年龄排i i 0 ? o2.getAge() - o1.getAge() : i;//如果年龄一样按照姓名首字母排i i 0 ? o2.getName().compareTo(o1.getName()) : i;//返回值//负数表示当前要添加的数据是小的存左边//正数表示当前要添加的数据是大的存右边//0表示当前要添加的元素已经存在舍弃return i;}});//添加学生对象ts.add(student1);ts.add(student2);ts.add(student3);ts.add(student4);ts.add(student5);//遍历输出集合System.out.println(方法二比较器排序:);IteratorStudent5 it ts.iterator();while (it.hasNext()) {Student5 s it.next();int num s.getEnglish() s.getMath() s.getChinese();System.out.println(s.getName() , s.getAge() , s.getChinese() , s.getMath() , s.getEnglish() , num);}/*张三,15,99,98,90,287王五,16,95,96,85,276赵六,19,93,68,83,244刘备,12,75,68,73,216李四,14,79,56,36,171*/}
}class Student5 {private String name;private int age;private int Chinese;private int Math;private int English;public Student5() {}public Student5(String name, int age, int Chinese, int Math, int English) {this.name name;this.age age;this.Chinese Chinese;this.Math Math;this.English English;}/*** 获取** return name*/public String getName() {return name;}/*** 设置** param name*/public void setName(String name) {this.name name;}/*** 获取** return age*/public int getAge() {return age;}/*** 设置** param age*/public void setAge(int age) {this.age age;}/*** 获取** return Chinese*/public int getChinese() {return Chinese;}/*** 设置** param Chinese*/public void setChinese(int Chinese) {this.Chinese Chinese;}/*** 获取** return Math*/public int getMath() {return Math;}/*** 设置** param Math*/public void setMath(int Math) {this.Math Math;}/*** 获取** return English*/public int getEnglish() {return English;}/*** 设置** param English*/public void setEnglish(int English) {this.English English;}public String toString() {return Student5{name name , age age , Chinese Chinese , Math Math , English English };}
}输出结果
4.3 排序方式的对比
定义方式 自然排序通过实现Comparable接口在类的定义中定义排序规则。 比较器排序通过实现Comparator接口在类的外部提供一个独立的比较器对象定义排序规则。
依赖性 自然排序依赖于类的定义对象必须实现Comparable接口来定义默认的自然排序规则。 比较器排序不依赖于类的定义可以根据不同的排序需求提供不同的比较器对象。
修改类定义 自然排序需要修改类的定义将实现Comparable接口并重写compareTo()方法来定义排序规则。 比较器排序无需修改类的定义可以提供一个独立的比较器对象来定义排序规则对类的定义没有侵入性。
灵活性 自然排序对于具体的类只能有一种自然排序规则不易灵活更改。 比较器排序可以根据具体的使用需求提供不同的比较器对象灵活定义不同的排序规则。
使用场景 自然排序适用于类的默认排序需求可以直接使用已定义的自然排序规则进行排序。 比较器排序适用于自定义的排序需求或者需要对无法修改类定义的类进行排序。
5. 注意事项 元素的可比较性TreeSet是基于红黑树实现的有序集合要保证集合中的元素是可比较的即元素类必须实现Comparable接口或传入一个比较器Comparator对象来比较元素的顺序。 元素的唯一性TreeSet不允许重复的元素存在。在插入新元素时TreeSet会根据元素的比较规则判断是否已经存在相同的元素如果存在则新元素不会被插入。 性能由于TreeSet是基于红黑树实现的插入、删除和查找操作的时间复杂度都是O(logN)其中N是集合中元素的个数。这使得TreeSet在大多数情况下具有较好的性能。但是与HashSet相比在非排序需求的情况下HashSet具有更好的性能。 无法使用null元素TreeSet不允许使用null元素。由于TreeSet需要比较元素并将其放入正确的位置如果集合中出现null元素则无法确定其正确的位置因此会抛出NullPointerException。 自然顺序和比较器TreeSet可以使用元素类的自然顺序如果元素类实现了Comparable接口也可以通过传入一个比较器对象来定义元素的顺序。在创建TreeSet时可以选择传入一个Comparator对象来进行自定义的排序比较。