1、我们知道在集合中,如果需要保持集合中的元素有序,则可以使用TreeSet集合。
2、TreeSet判断元素重复的方法和HashSet一样,但同时它还会保持集合中元素处于有序状态。
3、如果直接使用TreeSet的默认无参构造函数,则其工作起来会像使用sort()方法一样使用其中元素的compareTo()方法进行排序,所以此时其中的元素必须实现Comparable接口,并覆盖其中的CompareTo()方法(定义对象的比较规则)。
实例一:
package com.linwei;
import java.util.TreeSet;
public class TestTreeSetString {
public static void main(String[] args) {
new TestTreeSetString().go();
}
public void go(){
//String已实现Comparable接口,所以TreeSet使用String类覆写的compareTo()方法进行大小比较
TreeSet<String> tree =new TreeSet<String>();
tree.add("b");
tree.add("c");
tree.add("g");
tree.add("e");
tree.add("a");
tree.add("f");
System.out.println(tree);
}
}
执行输出:[a, b, c, e, f, g]
由于String类已经实现了Comparable接口,所以在TreeSet中可以直接使用,但如果是自定义的类,则必须自己实现Comparable接口,并覆盖compareTo()方法,编写自定义的比较规则。
再看下以下实例二:
package com.linwei;
import java.util.TreeSet;
public class TestTreeSet {
public static void main(String[] args) {
new TestTreeSet().go();
}
public void go(){
Book b1=new Book("How");
Book b2=new Book("Remix");
Book b3=new Book("Finding");
TreeSet<Book> tree =new TreeSet<Book>();
tree.add(b1);
tree.add(b2);
tree.add(b3);
System.out.println(tree);
}
class Book {
String title;
public Book(String t){
this.title=t;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public String toString() {
return "Book [title=" + title + "]";
}
}
}
问题一:以上程序代码能否通过编译?
答:能。
问题二:以上程序能否顺利执行?最终的执行结果是什么?
答:不能。
执行结果:Exception in thread "main" java.lang.ClassCastException: com.linwei.TestTreeSet$Book cannot be cast to java.lang.Comparable。
结果说明:很明显,异常是说Book对象不能转换为Comparable接口类型。
解决方法:修改Book类,实现Comparable接口,并覆盖其compareto()方法。
修改后代码如下实例二(修正):
package com.linwei;
import java.util.TreeSet;
public class TestTreeSet {
public static void main(String[] args) {
new TestTreeSet().go();
}
public void go(){
Book b1=new Book("How");
Book b2=new Book("Remix");
Book b3=new Book("Finding");
TreeSet<Book> tree =new TreeSet<Book>();
tree.add(b1);
tree.add(b2);
tree.add(b3);
System.out.println(tree);
}
class Book implements Comparable<Book>{
String title;
public Book(String t){
this.title=t;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public int compareTo(Book b) {
return getTitle().compareTo(b.getTitle());
}
@Override
public String toString() {
return "Book [title=" + title + "]";
}
}
}
执行结果:[Book [title=Finding], Book [title=How], Book [title=Remix]]
4、如果使用TreeSet带Comparator类型参数的构造函数,则必须另外单独创建一个专门的比较器对象(实现Comparator接口,并覆盖其中的compare()方法)。
实例三:
package com.linwei;
import java.util.Comparator;
import java.util.TreeSet;
public class TestTreeSet2 {
public static void main(String[] args) {
new TestTreeSet2().go();
}
public void go(){
Book b1=new Book("How");
Book b2=new Book("Remix");
Book b3=new Book("Finding");
//需传入一个Comparator类型的比较器对象
TreeSet<Book> tree =new TreeSet<Book>(new BookComparator());
tree.add(b1);
tree.add(b2);
tree.add(b3);
System.out.println(tree);
}
class Book {
String title;
public Book(String t){
this.title=t;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public String toString() {
return "Book [title=" + title + "]";
}
}
class BookComparator implements Comparator<Book>{
@Override
//覆写compare()方法,根据书名进行大小比较
public int compare(Book b1, Book b2) {
return b1.getTitle().compareTo(b2.getTitle());
}
}
}
执行结果:[Book [title=Finding], Book [title=How], Book [title=Remix]]