TreeSet与Comparable
TreeSet
TreeSet是一个有序的集合,它的作用是提供有序的Set集合。
1.TreeSet继承于AbstractSet,并且实现了NavigableSet接口。
2.TreeSet是一个包含有序的且没有重复元素的集合,通过TreeMap实现。TreeSet中含有一个"NavigableMap类型的成员变量"m,而m实际上是"TreeMap的实例"。
TreeSet的默认排序方式是自然排序,以如下代码演示
import java.util.TreeSet;
public class TreeSet_Demo {
public static void main(String[] args) {
TreeSet<String> data = new TreeSet();
data.add("C");
data.add("B");
data.add("A");
data.add("D");
for(String d:data){
System.out.println(d);
}
}
}
此时输出的结果为
A
B
C
D
即输出是通过ASCII码表的顺序排列的。
问题引入
那么如果我们传入TreeSet的不是字符串类型而是对象呢?
Person类如下
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
将Person对象添加进入TreeSet
import java.util.TreeSet;
public class TreeSet_Demo {
public static void main(String[] args) {
Person p1 = new Person("小王",18);
Person p2 = new Person("小李",19);
TreeSet<Person> data = new TreeSet();
data.add(p1);
data.add(p2);
for(Person d:data){
System.out.println(d);
}
}
}
此时运行程序报错
Exception in thread "main" java.lang.ClassCastException: class card.Person cannot be cast to class java.lang.Comparable (card.Person is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')
at java.base/java.util.TreeMap.compare(TreeMap.java:1563)
at java.base/java.util.TreeMap.addEntryToEmptyMap(TreeMap.java:768)
at java.base/java.util.TreeMap.put(TreeMap.java:777)
at java.base/java.util.TreeMap.put(TreeMap.java:534)
at java.base/java.util.TreeSet.add(TreeSet.java:255)
at card.TreeSet_Demo.main(TreeSet_Demo.java:10)
显示是出现了类型转换异常,在将Person类转换为Comparable类的时候出现了错误。那么Comparable类到底是什么呢?为什么在将Person对象存储时先要将Person类转换为Comparable类呢。
Comparable
Comparable是一个接口,如果想要让系统能对你的类做出牌序操作,那就需要实现Comparable,重写其中控制排序的方法,这个方法叫compareTo。
解决方法
修改Person类
public class Person implements Comparable<Person>{
private String name;
private int age;
@Override
public int compareTo(Person o) {
// this 与 o 进行比较
//返回的数据:负数表示this比o小
// 零表示this与o相等
// 负数表示this比o大
//以年龄比较为例
if (this.age>o.age){
return 1;
}else if(this.age==o.age){
return 0;
}else{
return -1;
}
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
将Person对象添加进入TreeSet
import java.util.TreeSet;
public class TreeSet_Demo {
public static void main(String[] args) {
Person p1 = new Person("小王",18);
Person p2 = new Person("小李",19);
Person p3 = new Person("小刘",20);
TreeSet<Person> data = new TreeSet();
data.add(p1);
data.add(p2);
data.add(p3);
for(Person d:data){
System.out.println(d);
}
}
}
此时运行结果如下
Person{name='小王', age=18}
Person{name='小李', age=19}
Person{name='小刘', age=20}