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

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='男'}

以下是 Java 常用的 100 个内置方法: 1. public static void main(String[] args):程序的主方法,是程序的入口。 2. System.out.println():输出数据到控制台。 3. Scanner scanner = new Scanner(System.in):从控制台读取用户输入。 4. Integer.parseInt():将字符串转换成整数。 5. Double.parseDouble():将字符串转换成双精度浮点数。 6. String.format():格式化字符串。 7. String.equals():比较两个字符串是否相等。 8. String.substring():获取子字符串。 9. String.indexOf():查找指定字符或子字符串的位置。 10. String.replace():替换字符串中的指定字符或子字符串。 11. String.split():根据指定字符或子字符串分割字符串。 12. String.toCharArray():将字符串转换成字符数组。 13. String.valueOf():将其他类型的数据转换成字符串。 14. Arrays.sort():对数组进行排序。 15. Arrays.asList():将数组转换成集合。 16. Collections.sort():对集合进行排序。 17. Collections.reverse():反转集合中的元素顺序。 18. Collections.shuffle():随机打乱集合中的元素顺序。 19. Math.abs():求绝对值。 20. Math.max():求两个数中的最大值。 21. Math.min():求两个数中的最小值。 22. Math.pow():求幂次方。 23. Math.sqrt():求平方根。 24. Math.round():四舍五入。 25. Math.random():生成一个随机数。 26. StringBuilder.append():将字符串添加到 StringBuilder 对象中。 27. StringBuilder.insert():在 StringBuilder 对象的指定位置插入字符串。 28. StringBuilder.delete():删除 StringBuilder 对象中的字符。 29. StringBuilder.reverse():反转 StringBuilder 对象中的字符。 30. File.exists():判断文件或目录是否存在。 31. File.isFile():判断路径是否为文件。 32. File.isDirectory():判断路径是否为目录。 33. File.getName():获取文件或目录的名称。 34. File.getAbsolutePath():获取文件或目录的绝对路径。 35. File.getParent():获取文件或目录的父级目录。 36. File.length():获取文件的大小。 37. File.delete():删除文件或目录。 38. FileInputStream.read():从文件中读取一个字节。 39. FileInputStream.read(byte[] b):从文件中读取一组字节。 40. FileInputStream.available():获取文件中还剩下的字节数。 41. FileOutputStream.write(int b):向文件中写入一个字节。 42. FileOutputStream.write(byte[] b):向文件中写入一组字节。 43. FileOutputStream.flush():刷新输出流,将缓冲区中的数据写入文件。 44. FileInputStream.close():关闭输入流。 45. FileOutputStream.close():关闭输出流。 46. BufferedReader.readLine():从文件中读取一行数据。 47. BufferedWriter.write(String s):向文件中写入一行数据。 48. BufferedWriter.flush():刷新输出流,将缓冲区中的数据写入文件。 49. BufferedReader.close():关闭输入流。 50. BufferedWriter.close():关闭输出流。 51. Date.toString():将日期对象转换成字符串。 52. SimpleDateFormat.format():将日期格式化成指定的字符串格式。 53. Calendar.getInstance():获取 Calendar 类的实例。 54. Calendar.get():获取 Calendar 对象中指定字段的值。 55. Calendar.set():设置 Calendar 对象中指定字段的值。 56. Calendar.add():为 Calendar 对象的指定字段添加或减去指定的时间量。 57. Arrays.copyOf():复制数组。 58. Arrays.fill():将数组中的元素全部设置为指定的值。 59. Arrays.binarySearch():在有序数组中查找指定的元素。 60. ArrayList.add():将元素添加到 ArrayList 集合中。 61. ArrayList.remove():从 ArrayList 集合中删除指定的元素。 62. ArrayList.get():获取 ArrayList 集合中指定索引位置的元素。 63. ArrayList.set():将 ArrayList 集合中指定索引位置的元素替换成指定元素。 64. ArrayList.contains():判断 ArrayList 集合中是否包含指定的元素。 65. ArrayList.isEmpty():判断 ArrayList 集合是否为空。 66. LinkedList.add():将元素添加到 LinkedList 集合中。 67. LinkedList.remove():从 LinkedList 集合中删除指定的元素。 68. LinkedList.get():获取 LinkedList 集合中指定索引位置的元素。 69. LinkedList.set():将 LinkedList 集合中指定索引位置的元素替换成指定元素。 70. LinkedList.contains():判断 LinkedList 集合中是否包含指定的元素。 71. LinkedList.isEmpty():判断 LinkedList 集合是否为空。 72. HashMap.put():将键值对添加到 HashMap 中。 73. HashMap.get():获取指定键的值。 74. HashMap.remove():从 HashMap 中删除指定键的键值对。 75. HashMap.containsKey():判断 HashMap 中是否包含指定的键。 76. HashMap.containsValue():判断 HashMap 中是否包含指定的值。 77. HashMap.keySet():获取 HashMap 中所有的键。 78. HashMap.values():获取 HashMap 中所有的值。 79. HashSet.add():将元素添加到 HashSet 集合中。 80. HashSet.remove():从 HashSet 集合中删除指定的元素。 81. HashSet.contains():判断 HashSet 集合中是否包含指定的元素。 82. HashSet.isEmpty():判断 HashSet 集合是否为空。 83. TreeSet.add():将元素添加到 TreeSet 集合中。 84. TreeSet.remove():从 TreeSet 集合中删除指定的元素。 85. TreeSet.contains():判断 TreeSet 集合中是否包含指定的元素。 86. TreeSet.isEmpty():判断 TreeSet 集合是否为空。 87. Iterator.hasNext():判断迭代器是否还有下一个元素。 88. Iterator.next():获取迭代器的下一个元素。 89. Iterator.remove():从迭代器所在的集合中删除元素。 90. Comparable.compareTo():比较两个对象的大小。 91. Comparator.compare():比较两个对象的大小。 92. Thread.start():启动线程。 93. Thread.sleep():让线程休眠指定的时间。 94. Thread.join():等待线程执行完毕。 95. Thread.yield():让出当前线程的 CPU 时间。 96. Thread.currentThread():获取当前线程对象。 97. Runnable.run():执行线程的任务。 98. ExecutorService.submit():将任务提交给线程池执行。 99. Future.get():获取线程池中某个任务的执行结果。 100. System.currentTimeMillis():获取当前的系统时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值