TreeSet集合经过了一系列操作,实现了Set接口
public class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, java.io.Serializable
{
……
}
public interface NavigableSet<E> extends SortedSet<E> {
……
}
public interface SortedSet<E> extends Set<E> {
……
}
观察他的构造方法可以发现常用的有第一个和第三个
也就是无参构造方法实现自然排序
带参构造方法内采用匿名内部类实现了Comparator接口(比较器)
无参构造 | 自然排序
我们先说无参构造方法
就以存储Student类对象为例子
package myCollection.set02;
/*这是Student类*/
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = 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;
}
}
package myCollection.set02;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
// 创建TreeSet集合对象,无参构造
TreeSet<Student> ts=new TreeSet<Student>();
// 创建Student对象
Student s1=new Student("xiyangyang",19);
Student s2=new Student("lanyangyang",15);
Student s3=new Student("meiyangyang",18);
Student s4=new Student("feiyangyang",20);
// 将学生对象添加到集合
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
// 使用循环遍历集合
for (Student s:ts){
System.out.println(s.getName()+","+s.getAge());
}
}
}
观察第二段代码会发现,遍历的时候出现了错误
也就是类类型转化异常,所以我们直接遍历显然是不行的
这里需要查看帮助文档对Student类进行操作。
上述文字也告诉我们,使用无参构造进行自然排序,插入到集合中的元素必须实现Comparable接口
随便观察JDK有的类可以发现
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence,Constable, ConstantDesc
{
……
}
public final class Integer extends Number
implements Comparable<Integer>, Constable, ConstantDesc
{
……
}
他们都实现了Comparable接口,所以咱们写的时候他自个儿排好序了
可是要是在集合中添加自定义类,不实现Comparable接口,就会报出类类型转化异常的错误
那好说,实现就行了,所以我们需要在Student类里implements一下Comparable接口
Comparable接口里只有一个抽象方法需要实现——compareTo
所以在Student类里重写compareTo方法就大功告成了
也就是这样
package myCollection.set02;
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;
}
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 int compareTo(Student s) {
//默认生成的
return 0;
}
}
这个时候再运行一下,会发现四个学生对象只存储进去了一个
我们再来细品一下compareTo()方法,compareTo()方法用于对元素之间比较
对于表达式 x.compareTo(y)
如果返回0,表示x==y
如果返回值 >0 表示 x > y
如果返回值 <0 表示 x < y
这个时候,就需要对compareTo()进行加工了
package myCollection.set02;
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;
}
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 int compareTo(Student s) {
// this是调用该方法的对象,也就是当前对象 s是之前的对象
// 比较年龄,如果后一个比前一个大,返回值大于0进行,升序排列
int num = this.age - s.age;
int num2 = num == 0 ? this.name.compareTo(s.name) : num;
return num2;
}
}
现在年龄已经按照升序的方式排序了
当年龄一样的时候,会返回0,这个时候对名字的内容进行排序,按照字典的顺序
package myCollection.set02;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
// 创建TreeSet集合对象,无参构造
TreeSet<Student> ts=new TreeSet<Student>();
// 创建Student对象
Student s1=new Student("xiyangyang",19);
Student s2=new Student("lanyangyang",15);
Student s3=new Student("meiyangyang",18);
Student s4=new Student("nicaiyangyang",20);
Student s5=new Student("feiyangyang",20);
// 将学生对象添加到集合
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
// 使用循环遍历集合
for (Student s:ts){
System.out.println(s.getName()+","+s.getAge());
}
}
}
如果想对年龄进行降序排序,同样需要修改返回值
package myCollection.set02;
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;
}
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 int compareTo(Student s) {
// this是调用该方法的对象,也就是当前对象 s是之前的对象
// 比较年龄,如果后一个比前一个大,返回值大于0进行,升序排列
int num = this.age - s.age;
int num2 = num == 0 ? this.name.compareTo(s.name) : num;
return num2;
}*/
@Override
public int compareTo(Student s) {
// 比较年龄,前一个比后一个大 前一个就在前面进行降序排列
int num = s.age - this.age;
return num;
}
}
带参构造 | 定制排序
带参构造,需要实现Comparator接口
此时,在没有让Student类实现Comparable接口时,可以使用带参构造创建匿名内部类
在带参的参数括号里创建一个子类对象,实现Comparator接口
package myCollection.set02;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
// 创建TreeSet集合对象,带参构造
TreeSet<Student> ts=new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// o1为当前对象 o2为之前的对象
// 年龄升序
int num = o1.getAge() - o2.getAge();
int num2 = num == 0 ? o1.getName().compareTo(o2.getName()) : num;
return num2;
}
});
// 创建Student对象
Student s1=new Student("xiyangyang",19);
Student s2=new Student("lanyangyang",15);
Student s3=new Student("meiyangyang",18);
Student s4=new Student("nicaiyangyang",20);
Student s5=new Student("feiyangyang",20);
// 将学生对象添加到集合
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
// 使用循环遍历集合
for (Student s:ts){
System.out.println(s.getName()+","+s.getAge());
}
}
}