java中TreeSet学习

向TreeSet中add的对象必须实现Comparable接口,并且是同一类型。否则会引起java.lang.ClassCastException异常。

class Err{}
public class TreeSetErrorTest
{
	public static void main(String[] args)
	{
		TreeSet ts = new TreeSet();
		// 向TreeSet集合中添加两个Err对象
		ts.add(new Err());
		ts.add(new Err());  //①
	}
}

public class TreeSetErrorTest2
{
	public static void main(String[] args)
	{
		TreeSet ts = new TreeSet();
		//HashSet ts = new HashSet();
		// 向TreeSet集合中添加两个对象
		ts.add(new String("疯狂Java讲义"));
		ts.add(new Date());   // ①
	}
}

对于TreeSet集合而言,它判断两个对象是否相等的唯一标准是:两个对象通compareTo(Object obj)方法比较是否返回0,如果 为0,TreeSet则会认为它们相等;否则就认为它们不相等。
当需要把一个对象放入TreeSet中,重写该对象对应类的equals()方法时,应该保证该方法与compareTo(Object obj)方法有一致的结果,其规则是:如果两个对象通过equals()方法比较返回true时,这两个对象通过compareTo(Object obj)方法比较应该返回0.

class Z implements Comparable
{
	int age;
	public Z(int age)
	{
		this.age = age;
	}
	// 重写equals()方法,总是返回true
	public boolean equals(Object obj)
	{
		return true;
	}
	// 重写了compareTo(Object obj)方法,总是返回1
	public int compareTo(Object obj)
	{
		return 1;
	}
}
public class TreeSetTest2
{
	public static void main(String[] args)
	{
		TreeSet set = new TreeSet();
		Z z1 = new Z(6);
		set.add(z1);
		set.add(z1);
		// 第二次添加同一个对象,输出true,表明添加成功
		System.out.println(set.add(z1));    //①
		// 下面输出set集合,将看到有两个元素
		System.out.println(set);
		// 修改set集合的第一个元素的age变量
		 ((Z)(set.first())).age = 9;
		// 输出set集合的最后一个元素的age变量,将看到也变成了9
		System.out.println(((Z)(set.last())).age);
		System.out.println(set.add(z1)); 
		System.out.println(set);
		Iterator it = set.iterator();
		while(it.hasNext()){
			Z z = (Z)it.next();
			System.out.println("age = "+z.age);
		}
	}
}
true
[c83.Z@15db9742, c83.Z@15db9742, c83.Z@15db9742]
9
true
[c83.Z@15db9742, c83.Z@15db9742, c83.Z@15db9742, c83.Z@15db9742]
age = 9
age = 9
age = 9
age = 9

class R2 implements Comparable
{
	int count;
	public R2(int count)
	{
		this.count = count;
	}
	public String toString()
	{
		return "R[count:" + count + "]";
	}
	// 重写equals方法,根据count来判断是否相等
	public boolean equals(Object obj)
	{
		if (this == obj)
		{
			return true;
		}
		if(obj != null && obj.getClass() == R2.class)
		{
			R2 r = (R2)obj;
			return r.count == this.count;
		}
		return false;
	}
	// 重写compareTo方法,根据count来比较大小
	public int compareTo(Object obj)
	{
		R2 r = (R2)obj;
		return count > r.count ? 1 :
			count < r.count ? -1 : 0;
	}
}
public class TreeSetTest3
{
	public static void main(String[] args)
	{
		TreeSet ts = new TreeSet();
		ts.add(new R2(5));
		ts.add(new R2(-3));
		ts.add(new R2(9));
		ts.add(new R2(-2));
		// 打印TreeSet集合,集合元素是有序排列的
		System.out.println(ts);    // ①
		// 取出第一个元素
		R2 first = (R2)ts.first();
		// 对第一个元素的count赋值
		first.count = 20;
		// 取出最后一个元素
		R2 last = (R2)ts.last();
		// 对最后一个元素的count赋值,与第二个元素的count相同
		last.count = -2;
		// 再次输出将看到TreeSet里的元素处于无序状态,且有重复元素
		System.out.println(ts);   // ②
		// 删除实例变量被改变的元素,删除失败
		System.out.println(ts.remove(new R2(-2)));   // ③
		System.out.println(ts);
		// 删除实例变量没有被改变的元素,删除成功
		System.out.println(ts.remove(new R2(5)));    // ④
		System.out.println(ts);
	}
}


[R[count:-3], R[count:-2], R[count:5], R[count:9]]
[R[count:20], R[count:-2], R[count:5], R[count:-2]]
false
[R[count:20], R[count:-2], R[count:5], R[count:-2]]
true
[R[count:20], R[count:-2], R[count:-2]]
当执行了代码
System.out.println(ts.remove(new R2(5)));    // ④
后,TreeSet会对集合中的元素重新索引(不是重新排序),接下来就可以删除TreeSet中的元素了,包括那些被修改过实例变量的元素。与HashSet类似的是,如果TreeSet中包含了可变对象,当可变对象的实例变量被修改时,TreeSet在处理这些对象时将非常复杂,而且容易出错。为了让程序更加健壮,推荐不要修改放入HashSet和TreeSet集合中元素的关键实例变量。

TreeSet实现定制排序:

class M
{
	int age;
	public M(int age)
	{
		this.age = age;
	}
	public String toString()
	{
		return "M[age:" + age + "]";
	}
}
public class TreeSetTest4
{
	public static void main(String[] args)
	{
		// 此处Lambda表达式的目标类型是Comparator
		TreeSet ts = new TreeSet((o1 , o2) ->
		{
			M m1 = (M)o1;
			M m2 = (M)o2;
			// 根据M对象的age属性来决定大小,age越大,M对象反而越小
			return m1.age > m2.age ? -1
				: m1.age < m2.age ? 1 : 0;
		});
		ts.add(new M(5));
		ts.add(new M(-3));
		ts.add(new M(9));
		System.out.println(ts);
	}
}

[M[age:9], M[age:5], M[age:-3]]

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值