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]]