您的位置:首页 > 编程语言 > Java开发

浅谈java中的TreeSet中的排序方式

2016-05-25 11:14 471 查看

TreeSet 和HashSet的区别

HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的,只不过Set用的只是Map的key

Map的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 hashcode