浅谈java中的TreeSet中的排序方式
2016-05-25 11:14
471 查看
TreeSet 和HashSet的区别
HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的,只不过Set用的只是Map的keyMap的key和Set都有一个共同的特性就是集合的唯一性.TreeMap更是多了一个排序的功能.
hashCode和equal()是HashMap用的, 因为无需排序所以只需要关注定位和唯一性即可.
a. hashCode是用来计算hash值的,hash值是用来确定hash表索引的.
b. hash表中的一个索引处存放的是一张链表, 所以还要通过equal方法循环比较链上的每一个对象
才可以真正定位到键值对应的Entry.
c. put时,如果hash表中没定位到,就在链表前加一个Entry,如果定位到了,则更换Entry中的value,并返回旧value
由于TreeMap需要排序,所以需要一个Comparator为键值进行大小比较.当然也是用Comparator定位的.
a. Comparator可以在创建TreeMap时指定
b. 如果创建时没有确定,那么就会使用key.compareTo()方法,这就要求key必须实现Comparable接口.
c. TreeMap是使用Tree数据结构实现的,所以使用compare接口就可以完成定位了.
**看完了上面我们发现 要使用TreeMap 那么必须在创建TreeMap时指定Comparator
或者TreeMap的key对象实现了Comparable接口 TreeSet同样也是如此
**
创建TreeSet时指定Comparator
首先创建一个Person 实体类其中有两个属性 name age 其并未实现Comparable 接口
package com.compare.test; public class Person{ private String name; private int age; public Person() { } public Person(String name, int age) { super(); this.name = name; this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }
PersonComparator 实现了Comparator 其中 只有一个方法
package com.compare.test; import java.util.Comparator; public class PersonComparator implements Comparator<Person> { public int compare(Person o1, Person o2) { if(o1.getAge()>o2.getAge()){ return 1; }else{ return -1; } } }
测试
package com.compare.test; import java.util.Iterator; import java.util.TreeSet; public class TestPerson { public static void main(String[] args) { Person p1 = new Person("z3", 15); Person p2 = new Person("qw", 30); Person p4 = new Person("ww", 23); Person p3 = new Person("xc", 10); TreeSet<Person> s = new TreeSet<Person>(new PersonComparator()); s.add(p3); s.add(p1); s.add(p2); s.add(p4); Iterator it = s.iterator(); while(it.hasNext()){ System.out.println(it.next()); } //System.out.println(s); } }
运行结果
Person [name=xc, age=10] Person [name=z3, age=15] Person [name=ww, age=23] Person [name=qw, age=30]
发现Person 类对象以age 从小到大排序
当我们把PersonComparator 实现了Comparator
方法返回值修改为
public int compare(Person o1, Person o2) { if(o1.getAge()>o2.getAge()){ return -1; }else{ return 1; } }
这时候 排序则为降序排列
Person [name=qw, age=30] Person [name=ww, age=23] Person [name=z3, age=15] Person [name=xc, age=10]
Person实现了Comparable接口
Person代码实现了Comparable 其他同上public class Person implements Comparable<Person>{ ... public int compareTo(Person o) { if(this.age > o.age){ return 1; }else{return -1;} } }
这时候创建TreeSet对象时就不用在构造方法中指定Comparator了
TreeSet<Person> s = new TreeSet<Person>();
其他代码同上
运行
Person [name=xc, age=10] Person [name=z3, age=15] Person [name=ww, age=23] Person [name=qw, age=30]
结果为升序
当修改compareto方法中的返回值后 修改方式同上
我们可以发现结果为降序了
总结
我们发现当person类 p1的age属性大于p2的值时P1代表前一个值,p2代表后一个值
即p1.age > p2.age
以下方法
public int compareTo(Person o) { if(this.age > o.age){ return 1; }else{return -1;} }
若为真时:
若返回正值 两者位置需要交换
而p1.age > p2.age 两者一交换p1在后面p2在前面
即值大的在后 值小的在前 形成了升序排列
若返回负值 两者不需要交换
而此时 p1.age 值大于p2.age 代表
值大的p1排在前面 值小的p2排在后面
形成了降序排列
**即treeset排序根据key.compareTo()方法排序时
若key.compareTo()方法的返回值为正则前后两个元素位置要发生交换
返回值为负则前后两个元素位置不发生交换
**
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树