Set接口的特点是:无序,不可以重复的元素集合
但是TreeSet集合可以给元素自然排序
public class TreeSetTest {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add("kkss");
ts.add("a");
ts.add("b");
ts.add("dff");
Iterator it = ts.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
结果:
a
b
dff
kkss
可以看到结果是按照字母的顺序来排序的
我自定义一个对象来添加到TreeSet集合中
public class TreeSetTest {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Student("al",22));
ts.add(new Student("sss",21));
ts.add(new Student("al",19));
ts.add(new Student("oop",21));
Iterator it = ts.iterator();
while(it.hasNext()){
Student stu = (Student)it.next();
System.out.println(stu.getName()+"............."+stu.getAge());
}
}
}
class Student{
private String name;
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;
}
private int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}
}
结果报错了
造成这个的原因是没有对自定义的类实现一个接口Comparable
为何要实现该接口呢?原因就是TreeSet这个集合它会把元素自然排序,排序是将调用Comparable接口的compareTo()方法,所以自定义的元素要实现该接口
public class TreeSetTest {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Student("al",22));
ts.add(new Student("sss",21));
ts.add(new Student("al",19));
ts.add(new Student("oop",21));
Iterator it = ts.iterator();
while(it.hasNext()){
Student stu = (Student)it.next();
System.out.println(stu.getName()+"............."+stu.getAge());
}
}
}
class Student implements Comparable<Student>{
private String name;
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;
}
private int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}
<span style="color:#ff0000;">public int compareTo(Student o) {
if(this.age>o.getAge()){
return 1;
}
if(this.age==o.getAge()){
return 0;
}
return -1;
}</span>
}
结果:
al.............19
sss.............21
al.............22
这回就正常了,不过还有个问题我添加了4个对象却输出了3个结果,这是因为在重写compareTo()时,判断语句返回0时(只按照年龄排序了),TreeSet会认为这两个对象是相同的,根据它的无重复性质它将不会添加另一个对象,我们应该判断姓名和年龄两个属性是否都相同才对
更改后代码
public class TreeSetTest {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Student("al",22));
ts.add(new Student("sss",21));
ts.add(new Student("al",19));
ts.add(new Student("oop",21));
Iterator it = ts.iterator();
while(it.hasNext()){
Student stu = (Student)it.next();
System.out.println(stu.getName()+"............."+stu.getAge());
}
}
}
class Student implements Comparable<Student>{
private String name;
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;
}
private int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}
public int compareTo(Student o) {
if(this.age>o.getAge()){
return 1;
}
<span style="color:#ff0000;">if(this.age==o.getAge()){
return this.name.compareTo(o.getName());
}</span>
return -1;
}
}
这里把姓名也进行排序判断
结果:
al.............19
oop.............21
sss.............21
al.............22
所以当添加自定义对象到TreeSet时一定要实现Comparable接口,并且要写好判断的条件
还有一种常用的方式,就是如果没有实现Comparable接口的话可以自定义一个类来实现Comparator接口并将这个类作为参数传给TreeSet集合,让集合去比较对象(这种方式更灵活,如果需求改变时只需要更改实现了Comparator接口的类的方法就可以)
public class TreeSetTest {
public static void main(String[] args) {
TreeSet ts = new TreeSet(new Mycompare());//接受一个自定义并且实现了Comparator接口的类
ts.add(new Student("al",22));
ts.add(new Student("sss",21));
ts.add(new Student("al",19));
ts.add(new Student("oop",21));
Iterator it = ts.iterator();
while(it.hasNext()){
Student stu = (Student)it.next();
System.out.println(stu.getName()+"............."+stu.getAge());
}
}
}
class Student implements Comparable<Student>{
private String name;
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;
}
private int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}
public int compareTo(Student o) {
if(this.age>o.getAge()){
return 1;
}
if(this.age==o.getAge()){
return this.name.compareTo(o.getName());
}
return -1;
}
}
//这里需求改变了,先按照姓名排
class Mycompare implements Comparator<Student>{
public int compare(Student o1, Student o2) {
int num = o1.getName().compareTo(o2.getName());
if(num==0){//如果名字相同就判断年龄
return new Integer(o1.getAge()).compareTo(new Integer(o2.getAge()));
}
return num;
}
}
结果:
al.............19
al.............22
oop.............21
sss.............21
所以推荐使用Comparator接口