13.4.2 Set接口的常用子类(2)
以上程序代码出现了类转换异常,会出现这样的问题,是因为TreeSet中的元素是有序存放,所以对于一个对象必须指定好其排序规则,且TreeSet中的每个对象所在的类都必须实现Comparable接口才可以正常使用。
范例:指定排序规则
- package org.lxh.demo13.setdemo;
- import java.util.Set;
- import java.util.TreeSet;
- class Person implements Comparable<Person> { //
定义Person类,实现比较器- private String name; // 定义name属性
- private int age; // 定义age属性
- public Person(String name, int age) { // 通过构造方法为属性赋值
- this.name = name; // 为name属性赋值
- this.age = age; // 为age属性赋值
- }
- public String toString() { // 覆写toString()方法
- return "姓名:" + this.name + ";年龄:" + this.age;
- }
- public int compareTo(Person per) { // 覆写compareTo()方法,
- 指定排序规则
- if (this.age > per.age) { // 通过年龄排序
- return 1;
- } else if (this.age < per.age) {
- return -1;
- }else{
- return 0 ;
- }
- }
- }
- public class TreeSetDemo03 {
- public static void main(String[] args) {
- Set<Person> allSet = new TreeSet<Person>();// 实例化Set接口对象
- allSet.add(new Person("张三", 30)); // 加入元素
- allSet.add(new Person("李四", 31)); // 加入元素
- allSet.add(new Person("王五", 32)); // 加入元素
- allSet.add(new Person("王五", 32)); // 重复元素,不能加入
- allSet.add(new Person("王五", 32)); // 重复元素,不能加入
- allSet.add(new Person("赵六", 33)); // 加入元素
- allSet.add(new Person("孙七", 33)); // 年龄重复
- System.out.println(allSet); // 输出集合,调用
- toString()
- }
- }
程序运行结果:
- [姓名:张三;年龄:30, 姓名:李四;年龄:31,
姓名:王五;年龄:32, 姓名:赵六;年龄:33]
从程序的运行结果中可以发现,重复的"王五"对象只有一个了;"赵六"和"孙七"的数据中姓名并不重复,只是年龄重复了,但是"孙七"却没有加入到集合中。这是由于采用了比较器造成的,因为比较器操作时如果某个属性没有进行比较的指定,则也会认为是同一个对象,所以此时应该在Person类的compareTo方法中增加按姓名比较。
范例:修改Person的比较器
- package org.lxh.demo13.setdemo;
- import java.util.Set;
- import java.util.TreeSet;
- class Person implements Comparable<Person> { // 定义Person类,实现比较器
- private String name; // 定义name属性
- private int age; // 定义age属性
- public Person(String name, int age) { // 通过构造方法为属性赋值
- this.name = name; // 为name属性赋值
- this.age = age; // 为age属性赋值
- }
- public String toString() { // 覆写toString()方法
- return "姓名:" + this.name + ";年龄:" + this.age;
- }
- public int compareTo(Person per) { // 覆写compareTo()方法,
- 指定排序规则
- if (this.age > per.age) { // 通过年龄排序
- return 1;
- } else if (this.age < per.age) {
- return -1;
- }else{
- return this.name.compareTo(per.name) ; // 增加字符串的比较
- }
- }
- }
- public class TreeSetDemo04 {
- public static void main(String[] args) {
- Set<Person> allSet = new TreeSet<Person>();// 实例化Set接口对象
- allSet.add(new Person("张三", 30)); // 加入元素
- allSet.add(new Person("李四", 31)); // 加入元素
- allSet.add(new Person("王五", 32)); // 加入元素
- allSet.add(new Person("王五", 32)); // 重复元素,不能加入
- allSet.add(new Person("王五", 32)); // 重复元素,不能加入
- allSet.add(new Person("赵六", 33)); // 加入元素
- allSet.add(new Person("孙七", 33)); // 年龄重复
- System.out.println(allSet); // 输出集合,调用
- toString()
- }
- }
程序运行结果:
- [姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:
王五;年龄:32, 姓名:孙七;年龄:33, 姓名:赵六;年龄:33]
以上的程序运行结果中出现了"孙七",而且去掉了重复的内容,但此时的重复内 容去掉,并不是真正意义上的去掉重复元素。因为此时靠的是Comparable完成的,而如果 换成HashSet则也会出现重复的内容,所以要想真正地去掉重复元素,则必须深入研究 Object类。