Collections中的sort()方法、compareTo()方法、max()方法、min()方法

3 篇文章 0 订阅

sort是进行collection集合进行排序使用的方法。会自动调用compareTo()方法,对集合进行排序。

一般步骤:

要排序的类要实现Comparable<?>接口,然后重写compareTo()方法;最后再调用sort(Collection)方法。调用sort()方法以后,sort()方法会自动调用compareTo()方法。

sort源码:实力尚浅,暂不分析。

代码:

public class CollectionTest1 implements Comparable<CollectionTest1>{

    private String name;
    private Integer age;
    private String gender;

    public CollectionTest1() {

    }

    public CollectionTest1(String name, Integer age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "CollectionTest1{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }

    @Override
    public int compareTo(CollectionTest1 person) {

        if (person.age>this.age){
            return 1;
        }else if (person.age==this.age){
            return 0;
        }else {
            return -1;
        }
    }

    public static void main(String[] args) {
        List<CollectionTest1> list = new ArrayList<>();
        list.add(new CollectionTest1("张三",20,"男"));
        list.add(new CollectionTest1("李四",24,"男"));
        list.add(new CollectionTest1("王五",23,"女"));
        list.add(new CollectionTest1("赵六",26,"男"));
        list.add(new CollectionTest1("孙七",18,"女"));
        list.add(new CollectionTest1("周八",18,"女"));


        System.out.println("排序前:");
        for (CollectionTest1 collectionTest1 : list) {
            System.out.println(collectionTest1.toString());
        }
        Collections.sort(list);
        System.out.println("排序后:-----------------------------------------");
        for (CollectionTest1 collectionTest1 : list) {
            System.out.println(collectionTest1.toString());
        }

说明:

实现Comparable<T>接口之后,compareTo()方法必须要被重写,增加业务逻辑。

浅析compareTo()方法:

(本人目前是个初学者,看不太明白源码,只能是自话自说,如与事实不符,敬请在评论区斧正!)

一般compareTo()方法中,进行排序的业务代码都是返回1,0,-1。其中this代指即将传入的对象,然后.出可比较的属性。

返回1就代表 要比较的元素在被比较元素  的后面,继续向后比较;

返回-1就代表 要比较的元素在被比较元素  的前面,不再继续向后比较;

返回0就代表 要比较的元素和被比较元素 相等,先来后到,放在被比较数的后面,不再向后比较;

用目前的眼光看来,比较时与List集合中的元素逐个比较(一开始是空的),比较后的数据按顺序放在此List集合中。

规则:

this.属性>集合传入对象.属性,返回1;

this.属性==集合传入对象.属性,返回0;

this.属性<集合传入对象.属性,返回-1。

这样排的顺序是从小到大排列;

反过来:

this.属性<集合传入对象.属性,返回1;

this.属性==集合传入对象.属性,返回0;

this.属性>集合传入对象.属性,返回-1。

这样的排序是从大到小排列。

下面为个人理解:

在重写compareTo()方法时,传入的对象规定List集合的类型,初始化为空List对象集合。等比较的时候,将传入的属性值与List集合中的元素对应属性值进行逐个比较,以此来确定将要存放的位置。所以速度较慢。

以上述代码中例子为例:根据年龄age排序

第一次比较:this.age是20,person.age是List<CollectionTest1>中取出的元素对象属性值,一开始没有数据,所以为null,看作0。this.age>person.age,返回1,现在的List集合中[20];

第二次比较:this.age是24,person.age是20,this.age>person.age,返回-1,现在List集合中[24,20];

第三次比较:this.age是23,第一个person.age是24,this.age<person.age,返回1;第二个person.age是20,this.age>person.age,返回-1。现在List集合中[24,23,20];

第四次比较:this.age是26,第一个person.age是24,this.age>person.age,返回-1;现在List集合中[26,24,23,20];

第五次比较:this.age是18,第一个person.age是26,this.age<person.age,返回1,继续比较;

                                             第二个person.age是24,this.age<person.age,返回1,继续比较;

                                             第三个person.age是23,this.age<person.age,返回1,继续比较;

                                             第四个person.age是20,this.age<person.age,返回1,继续比较;

                这时候List集合已经没有可以比较的元素了,所以 

                              第五个person.age是null,看作0,this.age>person.age,返回-1,停止比较;

现在List集合中[26,24,23,20,18];

第六次比较,this.age是18,第一个person.age是26,this.age<person.age,返回1,继续比较;

                                             第二个person.age是24,this.age<person.age,返回1,继续比较;

                                             第三个person.age是23,this.age<person.age,返回1,继续比较;

                                             第四个person.age是20,this.age<person.age,返回1,继续比较;

 第五个person.age是18,this.age==person.age,返回0,直接放在被比较数的后面,停止比较;

现在List集合中[26,24,23,20,18,18];

所以排序后,遍历结果是    26,24,23,20,18,18   对应的元素对象。

max和min:

源码:

---------------------max----------------------------

public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
        Iterator<? extends T> i = coll.iterator();
        T candidate = i.next();

        while (i.hasNext()) {
            T next = i.next();
            if (next.compareTo(candidate) > 0)
                candidate = next;
        }
        return candidate;
    }




-------------------min----------------------------

public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) {
        Iterator<? extends T> i = coll.iterator();
        T candidate = i.next();

        while (i.hasNext()) {
            T next = i.next();
            if (next.compareTo(candidate) < 0)
                candidate = next;
        }
        return candidate;
    }

Collections中的max()和min()方法根据compareTo()中的规则进行判断取值规则写反,就取反。

为何写反取反?因为源码中判断是这样的:根据返回值来判断,然后赋值。

比如max方法中

先是定义迭代器Iterator迭代集合元素,然后定义一个变量candidate,接收next()指针指向的当前元素。

紧接着开始使用while遍历集合,新定义一个变量next,将指针指向的当前元素赋值给它。

然后使用我们重写的compareTo()方法进行if条件分支判断注意,这里是next在前,candidate在后进行比较。若后一个元素与前一个元素的compareTo()方法返回的值是1,证明前一个元素大于后一个元素,而1>0为true,则将后一个元素next的值赋给前一个元素candidate。若为false则不赋值。然后直到遍历完成,返回candidate。

min方法同理。写反取反

所以会出现下面的结果:

年龄最大:CollectionTest1{name='周八', age=18, gender='女'}
年龄最小:CollectionTest1{name='赵六', age=26, gender='男'}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值