Java中的自然排序

博客给出Java编程例题,要求编写一个类,对其成员变量按多种规则进行自然排序。包括直接实现接口按年龄从小到大排序,利用接口通过匿名内部类实现从大到小、按对象长短排序,还需综合排序,用表达式指向方法。

例题

编写一个Dog类。其成员变量有:

int age;
String name;
double price;

按以下要求进行自然排序:

  • 直接实现Comparable接口,按照年龄从小到大对Dog数组进行自然排序
package com.cskaoyan.comparatorhomework;

import java.util.Arrays;

public class Demo {
    public static void main(String[] args) {
        //创建数组
        Dog[] dogs = new Dog[7];

        //创建对象
        dogs[0] = new Dog(4,"柯基",1300);
        dogs[1] = new Dog(4,"花花",800);
        dogs[2] = new Dog(3,"边牧",1500);
        dogs[3] = new Dog(5,"哈士奇",1100);
        dogs[4] = new Dog(2,"拉布拉多",1500);
        dogs[5] = new Dog(2,"中华田园犬",2000);
        dogs[6] = new Dog(6,"小狐狸",700);

        //排序
        Arrays.sort(dogs);
        //输出
        for (Dog d : dogs) {
            System.out.println(d);
        }

    }
}

class Dog implements Comparable{
    //成员变量
    int age;
    String name;
    double price;

    //三参构造器
    public Dog(int age, String name, double price) {
        this.age = age;
        this.name = name;
        this.price = price;
    }

    //重写toString方法
    @Override
    public String toString() {
        return "Dog{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

    @Override
    //实现Comparable接口,重写compareTo方法
    public int compareTo(Object o) {
        //按照年龄的大小从小到大排序
        //这里出现了强转,使用泛型可以不写强转
        return age - ((Dog) o).age;
    }
}

在这里插入图片描述

  • 利用Comparator接口,用匿名内部类和lambda分别对Dog数组进行自然排序。
    ①按照price从大到小排序
package com.cskaoyan.comparatorhomework;

import java.util.Arrays;
import java.util.Comparator;

public class Demo {
    public static void main(String[] args) {
        //创建数组
        Dog[] dogs = new Dog[7];

        //创建对象
        dogs[0] = new Dog(4,"柯基",1300);
        dogs[1] = new Dog(4,"花花",800);
        dogs[2] = new Dog(3,"边牧",1500);
        dogs[3] = new Dog(5,"哈士奇",1100);
        dogs[4] = new Dog(2,"拉布拉多",1500);
        dogs[5] = new Dog(2,"中华田园犬",2000);
        dogs[6] = new Dog(6,"小狐狸",700);

        //排序 匿名内部类
        //Comparator接口,重写compare方法
        //<Dog>是泛型,可以省略强转
        Arrays.sort(dogs, new Comparator<Dog>() {
            @Override
            public int compare(Dog o1, Dog o2) {
                //price是double类型,需要强转为int
                return (int) (o2.price - o1.price);
            }
        });
        //输出
        for (Dog d : dogs) {
            System.out.println(d);
        }
    }
}

class Dog{
    //成员变量
    int age;
    String name;
    double price;

    //三参构造器
    public Dog(int age, String name, double price) {
        this.age = age;
        this.name = name;
        this.price = price;
    }

    //重写toString方法
    @Override
    public String toString() {
        return "Dog{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

在这里插入图片描述

②按照name的长短排序,name越长对象越大

package com.cskaoyan.comparatorhomework;

import java.util.Arrays;

public class Demo {
    public static void main(String[] args) {
        //创建数组
        Dog[] dogs = new Dog[7];

        //创建对象
        dogs[0] = new Dog(4,"柯基",1300);
        dogs[1] = new Dog(4,"花花",800);
        dogs[2] = new Dog(3,"边牧",1500);
        dogs[3] = new Dog(5,"哈士奇",1100);
        dogs[4] = new Dog(2,"拉布拉多",1500);
        dogs[5] = new Dog(2,"中华田园犬",2000);
        dogs[6] = new Dog(6,"小狐狸",700);

        //排序 lambda表达式
        /*Arrays.sort(dogs,(d1,d2) -> {
            return d2.name.length() - d1.name.length();
        });*/
        //以上代码可以压行:去掉return和大括号
        Arrays.sort(dogs,(d1,d2) -> d2.name.length() - d1.name.length());
        //输出
        for (Dog d : dogs) {
            System.out.println(d);
        }
    }
}

class Dog{
    //成员变量
    int age;
    String name;
    double price;

    //三参构造器
    public Dog(int age, String name, double price) {
        this.age = age;
        this.name = name;
        this.price = price;
    }

    //重写toString方法
    @Override
    public String toString() {
        return "Dog{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

在这里插入图片描述

  • 综合age,name,price进行排序,要求用lambda表达式指向一个方法。 排序的规则是age越小对象越小,age相同比较name长短,name越短对象越小,name长度也相等,比较priceprice越大对象越小
package com.cskaoyan.comparatorhomework;

import java.util.Arrays;

public class Demo {
    public static void main(String[] args) {
        //创建数组
        Dog[] dogs = new Dog[7];

        //创建对象
        dogs[0] = new Dog(4,"柯基",1300);
        dogs[1] = new Dog(4,"花花",800);
        dogs[2] = new Dog(3,"边牧",1500);
        dogs[3] = new Dog(5,"哈士奇",1100);
        dogs[4] = new Dog(2,"拉布拉多",1500);
        dogs[5] = new Dog(2,"中华田园犬",2000);
        dogs[6] = new Dog(6,"小狐狸",700);

        //排序
        //lambda表达式 类名::方法名
        Arrays.sort(dogs,Demo::myCompara);
        //输出
        for (Dog d : dogs) {
            System.out.println(d);
        }

    }

    //排序的规则:从小到大排序
    //age越小对象越小,age相同比较name长短
    //name越短对象越小,name长度也相等,比较price
    //price越大对象越小
    public static int myCompara(Dog d1,Dog d2){
        if (d1.age != d2.age){
            return d1.age - d2.age;
        }

        if (d1.name != d2.name){
            return d1.name.length() - d2.name.length();
        }

        //代码执行到这里说明age相等且name的长度相等
        //price是double,需要强转为int
        return (int) (d2.price - d1.price);
    }
}

class Dog{
    //成员变量
    int age;
    String name;
    double price;

    //三参构造器
    public Dog(int age, String name, double price) {
        this.age = age;
        this.name = name;
        this.price = price;
    }

    //重写toString方法
    @Override
    public String toString() {
        return "Dog{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

在这里插入图片描述

### Java自然排序与定制排序 #### 自然排序 (Comparable) 在 Java 中,当对象实现了 `Comparable` 接口并覆写了 `compareTo()` 方法时,则该类的对象可以进行自然排序。这意味着这些对象能够按照某种默认顺序排列。 对于基本数据类型的数组以及实现了 `Comparable` 的对象数组可以直接调用 `Arrays.sort()` 进行升序排序[^1]: ```java import java.util.Arrays; class NaturalSortExample { public static void main(String[] args) { Integer arr[] = {-61, 10, -1, 7, 0, 89}; Arrays.sort(arr); System.out.println(Arrays.toString(arr)); } } ``` 上述代码会输出 `-61, -1, 0, 7, 10, 89` 表明整数已经按从小到大的顺序进行了排序[^3]。 如果希望自定义的类也支持这种行为,那么就需要让这个类实现 `Comparable<T>` 并提供具体的比较逻辑[^2]。 #### 定制排序 (Comparator) 相比之下,通过实现 `Comparator` 接口的方式更加灵活多变。这种方式允许开发者创建独立于被比较对象之外的比较器实例,在不修改原有类的情况下改变其排序规则[^4]。 下面是一个简单的例子展示了如何利用 Comparator 来完成降序排序: ```java import java.util.Arrays; import java.util.Comparator; class CustomComparator implements Comparator<Integer> { @Override public int compare(Integer o1, Integer o2) { return o2.compareTo(o1); // 反转参数位置以达到倒序效果 } } public class Main { public static void main(String[] args){ Integer arr[] = {-61, 10, -1, 7, 0, 89}; Arrays.sort(arr,new CustomComparator()); System.out.println(Arrays.toString(arr)); } } ``` 这段程序将会打印出 `[89, 10, 7, 0, -1, -61]`, 显示了列表中的元素已被成功反转为从大到小排列. #### 主要差异 - **适用范围**: 如果想要给某个特定类型设置固定的全局排序标准,应该优先考虑使用 Comparable;而当你只需要临时调整某些场景下的排序策略而不影响其他部分的行为模式时,Comparator 是更好的选择。 - **灵活性**: 使用 Comparator 不仅可以在运行期间动态指定不同的排序算法,还可以轻松处理更复杂的条件组合,例如基于多个字段联合判断先后次序等问题. - **侵入性**: 实现 Comparable 要求目标类本身做出改动,这可能会影响到整个系统的结构设计;相反地,借助外部 comparator 则完全不会干扰原始实体内部的状态维护机制.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值