java基础总结之比较器2种方式(常用类)

说明:

在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间 的比较问题

Java实现对象排序的方式有两种:

  • 自然排序:java.lang.Comparable
  • 定制排序:java.util.Comparator

方式一:Comparable(自然排序)

说明:

  • Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称 为类的自然排序。(一劳永逸的做法)
  • 实现 Comparable 的类必须实现 compareTo(Object obj) 方法
  • 对象的比大小排序本质上也是回归到属性上面的比较
  • 默认都是从小到大排列的
String: 按照字符串中字符的Unicode值进行比较

Character: 按照字符的Unicode值来进行比较

数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较

Boolean:true 对应的包装类实例大于 false 对应的包装类实例

Date、Time等:后面的日期时间比前面的日期时间大

基本类型和其他类型为啥能比较大小:
为什么Arrays.sort(数组);能进行排序呢?

原因:
java基础总结之比较器2种方式(常用类)_第1张图片
所以:

我们自己定义的对象(实体类)要进行比较大小也要实现这个类

规则呢?

重写compareTo(obj)的规则:
	如果当前对象this 大于 形参对象obj,则返回 正整数,
	如果当前对象this 小于 形参对象obj,则返回 负整数,
	如果当前对象this 等于 形参对象obj,则返回 零。

案例演示:

第一步:创建个自己的实体类例如:

package dateTest;


/**
 * 自己的实体类
 * @author suqinyi
 * @Date 2021/4/26
 */

//第一步:实现Comparable
public class Goods implements  Comparable{
     

    private String name;
    private double price;

    public Goods() {
     
    }

    public Goods(String name, double price) {
     
        this.name = name;
        this.price = price;
    }

    public String getName() {
     
        return name;
    }

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

    public double getPrice() {
     
        return price;
    }

    public void setPrice(double price) {
     
        this.price = price;
    }

    @Override
    public String toString() {
     
        return "Goods{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

    /**
     * 第二步重写compareTo()方法
     * 在补充比较逻辑
     */
    //逻辑:指明商品比较大小的方式:按照价格从低到高排序,再按照产品名称从高到低排序
    @Override
    public int compareTo(Object o) {
     
       System.out.println("****创建了*****");
        if(o instanceof Goods){
     
            Goods goods = (Goods)o;
            //方式一:
            if(this.price > goods.price){
     
                return 1;
            }else if(this.price < goods.price){
     
                return -1;
            }else{
     
//                return 0;
               return -this.name.compareTo(goods.name);
            }
            /**
             * 方式二:调用原本类型就有的比较方法
             */
//           return Double.compare(this.price,goods.price);
        }
//        return 0;
        throw new RuntimeException("传入的数据类型不一致!");
    }
}

第二步:测试代码:

	@Test
    public void test2(){
     
        Goods[] arr = new Goods[5];
        arr[0] = new Goods("lenovoMouse",34);
        arr[1] = new Goods("dellMouse",43);
        arr[2] = new Goods("xiaomiMouse",12);
        arr[3] = new Goods("huaweiMouse",65);
        arr[4] = new Goods("microsoftMouse",43);

        Arrays.sort(arr);

        System.out.println(Arrays.toString(arr));
    }

效果:
java基础总结之比较器2种方式(常用类)_第2张图片

BigDecimal是怎么样比对的呢?

java中对bigdimical比较大小一般用的是bigdemical的compareTo方法

//伪代码说明
int a = bigdemical.compareTo(bigdemical2)

a = -1,表示bigdemical小于bigdemical2

a = 0, 表示bigdemical等于bigdemical2

a = 1, 表示bigdemical大于bigdemical2

案例:

   @Test
    public void test08(){
     

        BigDecimal score1 = new BigDecimal("-1.0000");
        BigDecimal score2 = new BigDecimal("-1.00");
        System.out.println(score1.compareTo(score2));// 输出:0 表示相等

        BigDecimal bigDecimal = new BigDecimal("1");
        int i = bigDecimal.compareTo(new BigDecimal("0"));
        System.out.println(i);// 输出:1 表示大于

        BigDecimal less1 = new BigDecimal("3.0000");
        BigDecimal less2 = new BigDecimal("9.00");
        System.out.println(less1.compareTo(less2));// 输出:-1 表示小于

        //业务逻辑
        if (bigDecimal.compareTo(new BigDecimal("0"))==0){
     
            //俩个数比较,如果相等的话,进入判断
        }
        /**
         * 写法二:BigDecimal.ZERO
         *  if(bigDecimal01.compareTo(BigDecimal.ZERO)==0){
         *         判断结果是否为0,结果为0则相等,否则不等
         *  }
         */
    }

结果:
java基础总结之比较器2种方式(常用类)_第3张图片

方式二:Comparable(自然排序)

说明:

Comparable是临时性的

  • 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序,强行对多个对象进行整体排序的比较
  • 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。
  • 可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。
  • 还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。

案例一(自己实现String数组的排序):

 	/*
    Comparator接口的使用:定制排序
    1.背景:
    当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,
    或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,
    那么可以考虑使用 Comparator 的对象来排序
    2.重写compare(Object o1,Object o2)方法,比较o1和o2的大小:
    如果方法返回正整数,则表示o1大于o2;
    如果返回0,表示相等;
    返回负整数,表示o1小于o2。
     */
     
     //这个案例是演示怎么操作而已,不采用String自带的排序,自己实现Comparator,实现排序
    @Test
    public void test3(){
     
        String[] arr = new String[]{
     "AA","CC","KK","MM","GG","JJ","DD"};
        Arrays.sort(arr,new Comparator(){
     

            //按照字符串从大到小的顺序排列
            @Override
            public int compare(Object o1, Object o2) {
     
                if(o1 instanceof String && o2 instanceof  String){
     
                    String s1 = (String) o1;
                    String s2 = (String) o2;
                    return -s1.compareTo(s2);
                }
//                return 0;
                throw new RuntimeException("输入的数据类型不一致");
            }
        });
        System.out.println(Arrays.toString(arr));
    }

运行结果:
在这里插入图片描述

案例二(自己的实体类):

注明:那个商品类Goods不用实现Comparable接口,什么操作的都没有

@Test
    public void test4(){
     
        Goods[] arr = new Goods[6];
        arr[0] = new Goods("lenovoMouse",34);
        arr[1] = new Goods("dellMouse",43);
        arr[2] = new Goods("xiaomiMouse",12);
        arr[3] = new Goods("huaweiMouse",65);
        arr[4] = new Goods("huaweiMouse",224);
        arr[5] = new Goods("microsoftMouse",43);

        Arrays.sort(arr, new Comparator() {
     
            //指明商品比较大小的方式:按照产品名称从低到高排序,再按照价格从高到低排序
            @Override
            public int compare(Object o1, Object o2) {
     
                if(o1 instanceof Goods && o2 instanceof Goods){
     
                    Goods g1 = (Goods)o1;
                    Goods g2 = (Goods)o2;
                    if(g1.getName().equals(g2.getName())){
     
                        return -Double.compare(g1.getPrice(),g2.getPrice());
                    }else{
     
                        return g1.getName().compareTo(g2.getName());
                    }
                }
                throw new RuntimeException("输入的数据类型不一致");
            }
        });

        System.out.println(Arrays.toString(arr));
    }

效果:
在这里插入图片描述

俩种方式的区别:

  1. Comparable接口的方式一旦一定,保证Comparable接口实现类的对象在任何位置都可以比较大小。
  2. Comparator接口属于临时性的比较。

完结

你可能感兴趣的:(java基础,java)