总结:集合框架(TreeSet)

TreeSet描述的是Set的一个变体--可实现排序功能的集合。将对象插入到TreeSet中时,会按照某种规则将对象插入到一个有序序列中,以保证TreeSet集合中的对象序列保持"升序"排列。

TreeSet中的排序方法是根据什么确定对象之间的“大小”关系呢?
所有可能排序的类都实现了java.lang.Comparable接口,该接口中只有一个抽象方法:
public int compareTo(Object obj)
注意:用户在实现compareTo()方法确定比较逻辑时,比较结果应该和equals90方法比较的结果一致。

TreeSet的用法:

TreeSet是依靠TreeMap来实现的
TreeSet是一个有序集合,她的元素 按照升序排列,默认是按照自然顺序排列,也就是说TreeSet中的对象元素需要实现Comparable接口。
TreeSet类中跟HashSet类一样也没有get()方法来获取列表中的元素,所以也只能通过迭代器方法来获取。

1,

  //TreeSet的范例
  TreeSet ts = new TreeSet();
  ts.add("bddda");
  ts.add("abd");
  ts.add("zgagl");
  ts.add("Dujlg");
  ts.add("acb");
  
  Iterator it= ts.iterator();
  while(it.hasNext()){
   System.out.println(it.next());
  }


运行结果:

Dujlg
abd
acb
bddda
zgagl

很明显,输出结果是排好序的,

结论:TreeSet会自动进行排序

2,

知识点:相同的对象不会重复存储,也就是TreeSet集合里的值不重复。

                存储到TreeSet集合的元素必须具有可比性,如果元素自身不具可比性,那么需要让集合自身具备可比性。如果元素有可比性,并且集合也有可比性,那么以集合(比较器)为主。

package fighting;

import java.util.Iterator;
import java.util.TreeSet;
/**
 * Set:无序,不可以重复元素。
 *   |--HashSet:数据结构是哈希表。线程是非同步的。
 * 	 |     保证元素唯一性的原理:判断元素的hashcode值是否相同。
 * 	 |     如果相同,还会继续判断元素的equals方法,是否为true。
 *   |--TreeSet:可以对Set集合中的元素进行排序。底层的数据结构是二叉树。
 *               保证元素唯一性的依据:compareTo方法return 0
 *                 
 *               TreeSet排序的第一种方式:让元素自身具备比较性。
 *               元素需要实现Comparable接口,覆盖compareTo方法。
 *               这种方式也称为元素的自然顺序,或者叫做默认顺序。
 *               
 *               TreeSet的第二种排序方式:当元素自身不具备比较性时,
 *               或者具备比较性不是所需要的,这时就需要让集合自身具备比较性。
 *               怎么实现呢?在集合初始化时,就有了比较方式。
 *               
 *               如果两种方式都具备了,那么以比较器为主
 */
public class TreeSetDemo {
	/**
	 * 往TreeSet中存储自定义对象,按照学生的的年龄排序
	 */
	public static void main(String[] args) {
		/**
		 * TreeSet集合存储对象时,要自动排序的,所以要保证存储的对象具有可比性,
		 * 使得对象实现Comparable接口即可
		 */
		TreeSet ts = new TreeSet();

		/**
		 * 技巧:如果想要按原样输出TreeSet集合的值,
		 * 只要把compareTo方法返回值设为固定值1即可。
		 * 原因:根据二叉树原理,每次都会让根节点的右节点存储
		 */
		ts.add(new Student("zhangsan",32));//①
		ts.add(new Student("lisi",20));//②
		ts.add(new Student("wanglu",21));//③
		ts.add(new Student("wanglu",21));//④
		ts.add(new Student("Dujlg",22));//⑤
		ts.add(new Student("Dujlg",19));//⑥
		ts.add(new Student("aaa",19));//⑦
		ts.add(new Student("zhaoliu",19));//⑧
		
		Iterator it= ts.iterator();
		while(it.hasNext()){
			Student stu = (Student)it.next();
			System.out.println(stu.getName()+":"+stu.getAge());
		}

	}

}

class Student implements Comparable{
	private String name;
	private int age;
	
	public Student(String name,int age){
		this.name=name;
		this.age=age;
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

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

	//对象实现Comparable接口的compareTo方法,就具备了可比性
	public int compareTo(Object obj) {
		if(!(obj instanceof Student)){
			throw new RuntimeException("不是学生对象");
		}
		Student s = (Student)obj;
		
		System.out.println(this.name+" compareTo "+s.name);
		if(this.age > s.age){
			return 1;
		}
		if(this.age==s.age){
			//注意:如果年龄相同,还要比较姓名是不是相同,只有所有属性都相同,对象才相等
			return this.name.compareTo(s.name);
		}
		return -1;
	}
}


运行结果:

Dujlg:19
aaa:19
zhaoliu:19
lisi:20
wanglu:21
Dujlg:22
zhangsan:32

结果是先按年龄排序,年龄相同,再比较姓名,按姓名排序。

3,在创建TreeSet对象时传递一个比较器来实现自己的排序方式

结论:当元素自身不具备比较性,或者具备的比较性不是所需要的,这时需要让容器自身具备比较性。

package fighting;

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

public class TreeSetDemo2 {

	/**
	 * 当元素自身不具备比较性,或者具备的比较性不是所需要的,
	 * 这时需要让容器自身具备比较性。
	 * 定义比较器,将比较器对象传给TreeSet集合的构造方法
	 * 
	 */
	public static void main(String[] args) {
		TreeSet ts = new TreeSet(new MyCompare());

		/**
		 * 技巧:如果想要按原样输出TreeSet集合的值,
		 * 只要把compareTo方法返回值设为固定值1即可。
		 * 原因:根据二叉树原理,每次都会让根节点的右节点存储
		 */
		ts.add(new Student("zhangsan",32));//①
		ts.add(new Student("lisi",20));//②
		ts.add(new Student("wanglu",21));//③
		ts.add(new Student("wanglu",21));//④
		ts.add(new Student("Dujlg",22));//⑤
		ts.add(new Student("Dujlg",19));//⑥
		ts.add(new Student("aaa",19));//⑦
		ts.add(new Student("zhaoliu",19));//⑧
		
		Iterator it= ts.iterator();
		while(it.hasNext()){
			Student stu = (Student)it.next();
			System.out.println(stu.getName()+":"+stu.getAge());
		}

	}

}

class MyCompare implements Comparator{
	public int compare(Object o1,Object o2){
		Student s1 = (Student)o1;
		Student s2 = (Student)o2;
		
		//如果名称相同,还要比较年龄是否相同,因为年龄是int型,没有compareTo方法,所以封装成Integer对象
		int num = s1.getName().compareTo(s2.getName());
		if(num==0){
			num = new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
		}
		return num;
	}
}



运行结果:

Dujlg:19
Dujlg:22
aaa:19
lisi:20
wanglu:21
zhangsan:32
zhaoliu:19


4,

结论:字符串长度方法返回的是基本类型,没有compareTo方法,为了使用这个方法,长度封装成Integer对象。

小技巧:如果想要按字符长度降序排列,那么可以在比较长度的时候,两个对象换换位置即可。像这样:

int num = new Integer(s2.length()).compareTo(s1.length());

if(num==0){num = s2.compareTo(s1);}

package fighting;

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

public class TreeSetDemo3 {

	/**
	 * 本实例实现按字符串长度输出字符串。
	 * 
	 * 由于默认的是按自然顺序输出,而不是按长度输出,
	 * 即具备的比较性不是所需要的情况。这时要用到比较器
	 * 注意:主要条件相等,要判断次要条件
	 */
	public static void main(String[] args) {
		TreeSet ts = new TreeSet(new Comparator(){
			public int compare(Object o1,Object o2){
				String s1 = (String)o1;
				String s2= (String)o2;
				int num = new Integer(s1.length()).compareTo(s2.length());
				//长度相等,要判断字符串内容是否相同
				if(num==0){
					num = s1.compareTo(s2);
				}
				return num;
			}
		});
		ts.add("aaaaa");
		ts.add("bbbbbbbbbbbb");
		ts.add("c");
		ts.add("eee");
		ts.add("ddd");
		
		Iterator it = ts.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}

	}

}

运行结果:

c
ddd
eee
aaaaa
bbbbbbbbbbbb

总结:TreeSet里存储对象,为了保证可比性,有两种方法:

一,元素自己实现Comparable接口,重写compareTo方法;

二,传递比较器给集合对象,比较器实现Comparator接口,重写compare方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值