TreeSet的特性
TreeSet在Set的元素不重复的基础之上引入排序的概念,其中对自身拥有Comparable的元素,可以直接进行排序,比如字符串,按照字母的自然顺序排序,此处说下对于自定义对象排序的方式。
1、存储元素的类实现Comparable接口
实现Comparable接口,其中只有一个方法
compareTo(Object obj)
obj:是用来比较的对象,也就是前边进入TreeSet的对象
继续以Person来举例,首先实现Person类,代码如下:
class Person implements Comparable { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } //特别要注意的是此处也是TreeSet识别重复元素的规则,当年龄一样的时候要判断姓名是否相同,否则若年龄相同的话就不能存入TreeSet public int compareTo(Object obj) { if(!(obj instanceof Person)) throw new RuntimeException("hehe"); Person p = (Person)obj; int ageGap = this.age - p.age; if(ageGap > 0) return 1; else if(ageGap < 0) return -1; else return this.getName().compareTo(p.getName()); } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public String getName() { return this.name; } public int getAge() { return this.age; } }
2、创建TreeSet时向其中加入Comparator
当元素不具备比较性时,此时只能为容器添加比较器来解决问题,当元素具备比较性,并且容器具备比较器,此时要以比较器为主。
继续以Person作为例子
定义Comparator
//注意Comparator是一个泛型接口 class PersonComparator implements Comparator<Person> { public int compare(Person p1, Person p2) { int number = p1.getName().compareTo(p2.getName()); //先判断姓名,再判断年龄,和Comparable一样的,只比较一个条件会导致另一个条件不同的元素无法存入TreeSet if(number == 0) return new Integer(p1.getAge()).compareTo(new Integer(p2.getAge())); else return number; } }
如何使用
public class Test { public static void main(String[] args) { //TreeSet的构造方法中有用于接收比较器 TreeSet<Person> ts = new TreeSet<>(new PersonComparator()); ts.add(new Person("zhangsi", 34)); ts.add(new Person("zhangsi", 25)); ts.add(new Person("lisi", 34)); ts.add(new Person("zhangsi", 567)); ts.add(new Person("wangwu", 84)); ts.add(new Person("zhangsi", 23)); Iterator<Person> it = ts.iterator(); while(it.hasNext()) { Person p = it.next(); System.out.println(p.getName()+"%%%%%"+p.getAge()); } } }