ITEEDU

Java Gossip: TreeSet

TreeSet实作Set接口与SortedSet接口,提供相关的方法让您有序的取出对应位置的对象,像是 first()、last()等方法,TreeSet是J2SE中唯一实作SortedSet接口的类别,它使用红黑树结构来对加入的对象进行排序。

看个简单的例子:

TreeSetDemo.java
package onlyfun.caterpillar;
import java.util.*;
public class TreeSetDemo {
	public static void main(String[] args) {
		Set set = new TreeSet();
		set.add("justin");
		set.add("caterpillar");
		set.add("momor");
		set.add("justin");
		Iterator iterator = set.iterator();
		while(iterator.hasNext()) {
			System.out.print(iterator.next() + " ");
		}
		System.out.println();
	}
}

由于加入的是String对象,执行结果会自动依字典顺序进行排序的动作:

caterpillar  justin momor

依字典顺序排序String对象是TreeSet预设的,如果您对对象有自己的一套排序顺序,您要实作一个 Comparator 对象,您要实作compare()方法,它必须传回整数值,如果对象顺序相同则传回0,传回正整数表示compare()方法的第一个对象大于第二个对象,反之则传回负整数。

举个实际的例子,假设您想要改变TreeSet依字典顺序排列加入的对象为相反的顺序:

CustomComparator.java
package onlyfun.caterpillar;
import java.util.Comparator;
public class CustomComparator implements Comparator {
	public int compare(T o1, T o2) {
		if (((T) o1).equals(o2))
		return 0;
		return ((Comparable) o1).compareTo((T) o2) * -1;
	}
}

在自订的Comparator中,如果两个对象的顺序相同会传回0,这在TreeSet中表示两个对象是同一个对象,TreeSet要求传入的对象必须实 作java.lang.Comparable接口,范例中只是简单的将原来compareTo()传回的值乘以负一,如此在TreeSet中就可以简单的 让排列顺序相反。

在建构TreeSet实例时一并指定自订的Comparator,例如:

TreeSetDemo2.java
package onlyfun.caterpillar;
import java.util.*;
public class TreeSetDemo2 {
	public static void main(String[] args) {
		// 自订Comparator
		Comparator comparator =
		new CustomComparator();
		Set set =
		new TreeSet(comparator);
		set.add("justin");
		set.add("caterpillar");
		set.add("momor");
		// 使用 enhanced for loop 显示对象
		for(String name : set) {
			System.out.print(name + " ");
		}
		System.out.println();
	}
}

执行的结果是相反的:

momor justin  caterpillar