Java中TreeSet使用注意

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

 

 

你可能感兴趣的:(java,comparable,comparator,TreeSet)