Java之TreeSet介紹

import java.util.Comparator;
import java.util.TreeSet;

import org.junit.Test;

//非線程安全
public class TreeSetTest {
	/**
	 * TreeSet:它可以給Set集合中的元素進行指定方式的排序。 保證元素唯一性的方式:通過比較的結果是否爲0. 底層數據結構是:二叉樹。
	 * 
	 * 排序的第一種方式: 讓元素自身具備比較性。只要讓元素實現Comparable接口,覆蓋compareTo方法即可。
	 * 
	 * 但是,如果元素自身不具備比較性,或者元素自身具備的比較性,不是所需要的。
	 * 比如,學生的自然排序是按年齡排序,現在想要按照學生姓名排序。還可以不改動原有代碼。 這時怎麼辦呢?
	 * 
	 * 排序的第二種方式:自定比較器的方式。這時可以讓集合自身具備比較性。
	 * 
	 * 可以定義一個類實現Comparator接口,覆蓋compare方法。
	 * 將該Comparator接口子類對象作爲實際參數傳遞給TreeSet集合構造函數。
	 */
	public static void main(String[] args) {
		TreeSet<Student> ts = new TreeSet<Student>();
		// Student如果不實現Comparable,add時會出錯,Student cannot be cast to java.lang.Comparable
		//添加第一個對象時,TreeSet裏沒有任何元素,所以沒有問題;
		//當添加第二個Err對象時,TreeSet就會調用該對象的compareTo(Object obj)方法與集合中其他元素進行比較——
		//如果對應的類沒有實現Comparable接口,則會引發ClassCastException異常
		// add方法內部會對插入的數據進行排序,此時元素自身具備比較性,因爲其實現了Comparable接口
		ts.add(new Student("lisi0", 30));
		ts.add(new Student("lisixx", 29));
		ts.add(new Student("lisi9", 29));
		ts.add(new Student("lisi8", 38));
		// 重複插入無效,但是不報錯(根據年齡和名字進行比較,都相同,視爲同一個學生)
		ts.add(new Student("lisixx", 29));
		ts.add(new Student("lisixx", 28));
		ts.add(new Student("lisi4", 14));
		ts.add(new Student("lisi7", 27));
		System.out.println(ts);
	}
	
	//此時根據自定義的比較器進行排序
	@Test
	public void testComparator() {
		// 可以利用匿名類,按名字進行排序
		TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {

			@Override
			public int compare(Student s1, Student s2) {
				int num = s1.getName().compareTo(s2.getName());
				return num;
			}
		});

		ts.add(new Student("lisi0", 30));
		ts.add(new Student("lisixx", 29));
		ts.add(new Student("lisi9", 29));
		ts.add(new Student("lisi8", 38));
		//此時根據名字進行排序,不管年齡是否相同,下面兩個都不會插入
		//名字相同,則視爲同一個人
		ts.add(new Student("lisixx", 29));
		ts.add(new Student("lisixx", 28));
		ts.add(new Student("lisi4", 14));
		ts.add(new Student("lisi7", 27));

		System.out.println(ts);
	}
	//奇數升序,偶數降序
	@Test
	public void mySort() {
		TreeSet set = new TreeSet(new Comparator() {
			int r = 0;
			@Override
			public int compare(Object a, Object b) {
				int n1 = Integer.parseInt(a.toString());
				int n2 = Integer.parseInt(b.toString());
				if (n1 % 2 != n2 % 2) {
					r = (n2 % 2 - n1 % 2);
				} else if (n1 % 2 == 1) {
					if (n1 > n2)
						r = 1;
					else if (n1 < n2)
						r = -1;
				} else if (n1 % 2 == 0) {
					if (n1 > n2)
						r = -1;
					else if (n1 < n2)
						r = 1;
				}
				return r;
			}
		});
		set.add("1");
		set.add("2");
		set.add("3");
		set.add("4");
		set.add("5");
		set.add("6");
		set.add("7");
		set.add("8");
		set.add("9");
		set.add("10");
		System.out.println(set);
	}

	// //同姓名同年齡的學生視爲同一個學生
	public static class Student implements Comparable<Student> {

		private int age;
		private String name;

		public Student(String name, int age) {
			this.age = age;
			this.name = name;
		}

		@Override
		public int compareTo(Student stu) {
			int num = new Integer(this.age).compareTo(new Integer(stu.age));
			return num == 0 ? this.name.compareTo(stu.name) : num;
		}

		public String toString() {
			return name + "::" + age;
		}

		public int getAge() {
			return age;
		}

		public void setAge(int age) {
			this.age = age;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章