java Set接口的实现类TreeSet 自然排序 定制排序

java Set接口的实现类TreeSet 自然排序 定制排序

1.TreeSet 自然排序

  1. TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序排列
  2. 如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口。
  3. 实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。
//当向TreeSet中添加Person类,确定按照哪个属性排列。一般会通过多个属性的比较,避免片面返回零
@Override
public int compareTo(Object o) {
	if(o instanceof Person) {
		Person p = (Person)o;
// 	return this.name.compareTo(p.name);//从小到大
	return -this.name.compareTo(p.name);//从大到小
	}else {
		return 0;
	}
}
@Override
public int compareTo(Object o) {
	if(o instanceof Person) {
		Person p = (Person)o;
		int i =  this.name.compareTo(p.name);
		if( i == 0 ) {
			return this.age.compareTo(p.age);
		}

	}
	return 0;
}
  1. Comparable 的典型实现:
    ①BigDecimal、BigInteger 以及所有的数值型对应的包装类:按它们对应的数值大小进行比较
    ②Character:按字符的 unicode值来进行比较
    ③Boolean:true 对应的包装类实例大于 false 对应的包装类实例
    ④String:按字符串中字符的 unicode 值进行比较
    ⑥Date、Time:后边的时间、日期比前面的时间、日期大

  2. 向 TreeSet 中添加元素时,只有第一个元素无须比较compareTo()方法,后面添加的所有元素都会调用compareTo()方法进行比较。

  3. 因为只有相同类的两个实例才会比较大小,所以向 TreeSet 中添加的应该是同一个类的对象

  4. 对于 TreeSet 集合而言,它判断两个对象是否相等的唯一标准是:两个对象通过 compareTo(Object obj) 方法比较返回值

  5. 当需要把一个对象放入 TreeSet 中,重写该对象对应的 equals() 方法时,应保证该方法与 compareTo(Object obj) 方法有一致的结果:如果两个对象通过 equals() 方法比较返回 true,则通过 compareTo(Object obj) 方法比较应返回 0,即

compareTo()与hashCode()以及equals()三者保持一致

  1. String、包装类等的自然排序
	/*
	 * 2.可以按照添加进集合的元素指定的顺序遍历,像String,包装类等默认顺序:从小到大
	 */
	@Test
	public void testTreeSet1() {
		Set set = new TreeSet<>();
		set.add("JJ");
		set.add(new String("MM"));
		set.add("AA");
		set.add("AA");
		set.add("BB");
		set.add("GG");
		for(Object obj : set) {
			System.out.println(obj);
		}

	}
  1. 当Person类没有实现Coparable接口时,向TreeSet中添加Person对象时,报ClassCastException
Set set = new TreeSet<>();
set.add(new Person("CC",12));

2.TreeSet 定制排序

  1. TreeSet的自然排序是根据集合元素的大小,进行元素升序排列。如果需要定制排序,比如降序排列,可通过Comparator接口的帮助。需要重写compare(T o1,T o2)方法。
  2. 利用int compare(T o1,T o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。
  3. 要实现定制排序,需要将实现Comparator接口的实例作为形参传递给TreeSet的构造器。
  4. 此时,仍然只能向TreeSet中添加类型相同的对象。否则发生ClassCastException异常。
  5. 使用定制排序判断两个元素相等的标准是:通过Comparator比较两个元素返回了0。
  6. demo
/*
 * TreeSet的定制排序:
 * 
 */
@Test
public void testTreeSet2() {
	//1. 创建一个实现了Comparator接口的对象
	Comparator com = new Comparator() {
		//向TreeSet中添加Customer类的对象,compare()方法中,
		//指明按照Customer的哪个属性进行排序
		@Override
		public int compare(Object o1, Object o2) {
			if(o1 instanceof Customer && o2 instanceof Customer ) {
				Customer c1 = (Customer)o1;
				Customer c2 = (Customer)o2;
				int i = c1.getId().compareTo(c2.getId());
				if(i == 0) {
					return c1.getName().compareTo(c2.getName());
				}
				return i;
			}
			return 0;
		}
		
	};
	//2.将此对象作为形参传递给TreeSet的构造器中
	TreeSet set = new TreeSet(com);
	//3.添加Comparator接口中的compare方法中涉及的类对象
	set.add(new Customer("AA",1003));
	set.add(new Customer("BB",1002));
	set.add(new Customer("GG",1004));
	set.add(new Customer("CC",1001));
	set.add(new Customer("DD",1007));
	
	for(Object obj : set) {
		System.out.println(obj);
	}

}
  1. compareTo()与hashCode()以及equals()三者保持一致

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值