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

TreeSet 和HashSet的区别

  1. HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的,只不过Set用的只是Map的key
  2. Map的key和Set都有一个共同的特性就是集合的唯一性.TreeMap更是多了一个排序的功能.
  3. hashCode和equal()是HashMap用的, 因为无需排序所以只需要关注定位和唯一性即可.
    a. hashCode是用来计算hash值的,hash值是用来确定hash表索引的.
    b. hash表中的一个索引处存放的是一张链表, 所以还要通过equal方法循环比较链上的每一个对象
    才可以真正定位到键值对应的Entry.
    c. put时,如果hash表中没定位到,就在链表前加一个Entry,如果定位到了,则更换Entry中的value,并返回旧value
  4. 由于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)