Java比较器Comparator进行排序及获取最大最小值

😂 这篇文章最后更新于1188天前,您需要注意相关的内容是否还可用。
目录导航
  • Java比较器Comparator使用/获取最大最小值
    • Comparator使用
    • Comparable使用
    • stream获取最大/小值
    • 对double等类型比较
    • stream排序
  • Java比较器Comparator使用/获取最大最小值

    Comparable:强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法 被称为它的自然比较方法。只能在类中实现compareTo()一次,不能经常修改类的代码实现自己想要的排序。实现 此接口的对象列表(和数组)可以通过Collections.sort(和Arrays.sort)进行自动排序,对象可以用作有序映射中 的键或有序集合中的元素,无需指定比较器。

    Comparator:强行对某个对象进行整体排序。可以将Comparator 传递给sort方法(如Collections.sort或 Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用Comparator来控制某些数据结构(如有序set或 有序映射)的顺序,或者为那些没有自然顺序的对象collection提供排序。

    Comparator使用

            ArrayList<Integer> list = new ArrayList<Integer>();
    //采用工具类 完成 往集合中添加元素
            Collections.addAll(list, 5, 222, 1, 2);
    //排序方法
            Collections.sort(list);
    //        输出排序后值 第一个最小 末位最大
            System.out.println(list);//[1, 2, 5, 222]
    
    //为对象排序
            ArrayList<String> list1 = new ArrayList<String>();
            list1.add("cba");
            list1.add("abc");
            list1.add("bca");
            Collections.sort(list1, new Comparator<String>() {
                @Override
    //            第一个参数代表较小的 第二个较大
                public int compare(String o1, String o2) {
                    return o1.charAt(0) - o2.charAt(0);
                }
            });
    //        Lamada改写
            Collections.sort(list1, (o1, o2) -> o1.charAt(0) - o2.charAt(0));
            Collections.sort(list1, Comparator.comparingInt(o -> o.charAt(0)));
            System.out.println(list1);//[abc, bca, cba]

    Comparable使用

    Student实体类

    import lombok.AllArgsConstructor;
    import lombok.Data;
    @Data
    @AllArgsConstructor
    public class Student implements Comparable<Student> {
        private String name;
        private int age;
    
        @Override
        public int compareTo(Student o) {
            return this.age - o.age;//升序
        }
    }

    或者用if判断重写

        @Override
        public int compareTo(Student o) {
        //升序
            if (this.age > o.age) {
                return 1;
            } else if (this.age < o.age){
                return -1;
            } else{
                return 0;
            }
        }

    测试

    // 创建四个学生对象 存储到集合中
            ArrayList<Student> list = new ArrayList<Student>();
            list.add(new Student("rose", 18));
            list.add(new Student("jack", 16));
            list.add(new Student("mark", 16));
            list.add(new Student("mona", 20));
    /*
    让学生 按照年龄排序 升序
    */
            Collections.sort(list);//要求 该list中元素类型 必须实现比较器Comparable接口
            for (Student student : list) {
                System.out.println(student);
            }

    stream获取最大/小值

    ArrayList<Integer> list = new ArrayList<>();
    Collections.addAll(list, 2, 5, 3, 8, 7, 9);
    Integer max = list.stream().max(Integer::compare).get();
    Integer min = list.stream().min(Integer::compare).get();
    System.out.println("最大" + max + ",最小" + min); //最大9,最小2

    针对与于对象,例如上述Student获取最大年龄跟最小年龄

    ArrayList<Student> list = new ArrayList<Student>();
    list.add(new Student("rose", 18));
    list.add(new Student("jack", 16));
    list.add(new Student("mark", 16));
    list.add(new Student("bob", 27));
    list.add(new Student("mona", 20));
    Student max = list.stream().max(Student::compareTo).get();
    Student min = list.stream().min(Student::compareTo).get();
    System.out.println(max);
    System.out.println(min);

    但是如果没有继承Comparable接口重写compareTo的话,就得代码比较年龄了

            ArrayList<Student> list = new ArrayList<Student>();
            list.add(new Student("rose", 18));
            list.add(new Student("jack", 16));
            list.add(new Student("mark", 15));
            list.add(new Student("bob", 27));
            list.add(new Student("mona", 20));
    //        取最大年龄 这里同样用Comparator
            Student max = list.stream().max(new Comparator<Student>() {
                @Override
                public int compare(Student a, Student b) {
                    if (a.getAge() > b.getAge()) {
                        return 1;
                    } else {
                        return -1;
                    }
                }
            }).get();
    //        取最小年龄 取较大值中最小值 这里也可以用max 不过就要将>改为<
            Student min = list.stream().min((a, b) -> {
                if (a.getAge() > b.getAge()) {
                    return 1;
                } else {
                    return -1;
                }
            }).get();
    //        Lamada简写
            Student max1 = list.stream().max((a, b) -> a.getAge()-b.getAge()).get();
            Student max2 = list.stream().max(Comparator.comparingInt(Student::getAge)).get();
    //        若跟参数a b顺序不对应的话无法简写成comparingInt 但max这时就成取最小值;
            Student min1 = list.stream().max((a, b) -> b.getAge()-a.getAge()).get();
            Student min2 = list.stream().min((a, b) -> a.getAge()-b.getAge()).get();
            System.out.println(min);
            System.out.println(min1);
            System.out.println(min2);
            System.out.println(max);
            System.out.println(max1);
            System.out.println(max2);

    对double等类型比较

    在Student实体类中加入Double hign身高属性,直接调用Comparator.comparingDouble方法,或者直接使用Comparator.comparing也可以。

    //        打印最高的学生
            Student studentMax = list.stream().max(Comparator.comparingDouble(Student::getHign)).get();
            Student studentMin = list.stream().min(Comparator.comparingDouble(Student::getHign)).get();
            System.out.println(studentMax);
            System.out.println(studentMin);
            Student studentMax1 = list.stream().max((a, b) -> {
                if (a.getHign() > b.getHign()) {
                    return 1;
                } else {
                    return -1;
                }
            }).get();
            Student studentMin1 = list.stream().min((a, b) -> {
                if (a.getHign() > b.getHign()) {
                    return 1;
                } else {
                    return -1;
                }
            }).get();
            System.out.println(studentMax1);
            System.out.println(studentMin1);
            Student studentMax2 = list.stream().max(Comparator.comparing(Student::getHign)).get();
            System.out.println(studentMax2);

    当然了,也可以用sort进行排序,对于double也可以使用上述策略

    //        年龄从低到高
            list.sort((a, b) -> a.getAge() - b.getAge());
            System.out.println(list);
    //        身高升序
            list.sort(Comparator.comparing(Student::getHign));
            System.out.println(list);
    //        身高降序 简而言之就是o2.getHign()-o1.getHign()>0,但是compare方法只返回int,强制类型转换会导致不精准
            list.sort(new Comparator<Student>() {
                @Override
                public int compare(Student o1, Student o2) {
                    if (o1.getHign() < o2.getHign()) {
                        return 1;
                    } else {
                        return -1;
                    }
                }
            });
            System.out.println(list);

    stream排序

    用sorted即可

    Stream<Student> asc = list.stream().sorted((a,b)->a.getAge()-b.getAge());
    asc = list.stream().sorted(Comparator.comparingInt(Student::getAge));
    Stream<Student> desc = list.stream().sorted((a,b)->b.getAge()-a.getAge());
    System.out.println(asc.collect(Collectors.toList()));
    System.out.println(desc.collect(Collectors.toList()));