Java对象的比较(详解三种比较方式)

一、基本类型的比较

对于Java中的基本类型而言,Java可以对其直接比较。整型浮点型就是直接比较其大小,字符型则是按照其背后的编码大小进行比较。

二、引用类型的比较

对于引用而言,Java中默认情况下只能对其地址进行比较,并且我们只能判断其是否相等,而不能进行大于小于的比较。也就是说,当我们使用==判断其是否相等的时候,Java只会比较两个引用所指向的地址是否相等,不会比较其所指对象的具体内容。

class A{

}
public class test1 {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new A();
        //返回false
        System.out.println(a1 == a2);
        //报错
        System.out.println(a1 > a2);
        //报错
        System.out.println(a1 < a2);
    }
}

三、三种自定义比较的方式

1、重写equals()方法

如果我们想判断两个引用对象的内容是否相等,我们可以调用equals()方法。这个方法定义在Object类中,而我们的类都继承了Object类。所以我们自己定义的类都可以使用这个方法。

但如果我们不在自定义类中重写这个方法的话,这个方法默认实现的也是对两个引用对象地址的比较。
默认实现如下:

public boolean equals(Object obj) {
    return (this == obj);
}

但这里有一个例外,就是我们的String类型,这个类比较特殊,这个类的内部已经重写了equals()方法,其重写后就是在比较字符串中的具体内容。

比如下面的代码:

class Card {
    public int rank;
    public String suit;

    @Override
    public boolean equals(Object obj) {
        // 自己和自己比较
        if(this == obj)
            return true;
        //o如果是null对象,或者o不是Card的子类
        if(obj == null || !(obj instanceof Card))
            return false;
        //注意基本类型可以直接比较,但引用类型最好调用其equal方法
        Card c = (Card) obj;
        return this.rank == c.rank && this.suit.equals(c.suit);
    }
}

但是我们发现重写equals方法只能够比较两个对象是否相等,其大小关系我们是比较不了的。所以如果我们想要比较两个引用对象的大小关系,我们就需要使用到下面的两种方法了。

2、基于Comparble接口比较

Comparble是一个Java提供的接口,这个接口的源码如下:

public interface Comparable<E> {
	int compareTo(E o);
	// 返回值:
	// < 0: 表示 this 指向的对象小于 o 指向的对象
	// == 0: 表示 this 指向的对象等于 o 指向的对象
	// > 0: 表示 this 指向的对象大于 o 指向的对象
}

如果我们想自定义比较两个类的大小关系的话,只需要让我们写的类实现这个接口即可。

示例如下:

class Card implements Comparable<Card>{
    public int rank;
    public String suit;

    @Override
    public boolean equals(Object obj) {
        // 自己和自己比较
        if(this == obj)
            return true;
        //o如果是null对象,或者o不是Card的子类
        if(obj == null || !(obj instanceof Card))
            return false;
        //注意基本类型可以直接比较,但引用类型最好调用其equal方法
        Card c = (Card) obj;
        return this.rank == c.rank && this.suit.equals(c.suit);
    }

    @Override
    public int compareTo(Card o) {
        return this.rank - o.rank;
    }
}

那么当我们需要比较两个类的大小关系的时候,直接调用compareTo()成员函数即可。

//p,q为Card类型的实例化对象。
System.out.println(p.compareTo(q));

3、基于Comparator比较器进行比较

Comparator比较器也是Java提供的一个接口,其实现如下:

public interface Comparator<T> {
	int compare(T o1, T o2);
	// 返回值:
	// < 0: 表示 o1 指向的对象小于 o2 指向的对象
	// == 0: 表示 o1 指向的对象等于 o2 指向的对象
	// > 0: 表示 o1 指向的对象等于 o2 指向的对象
}

这个比较器和第二个比较器的使用方法是不同的,这个接口并不是由我们的自定义类实现,而是我们要在定义一个专门的接口实现类来实现这个接口。

比如:

class Card {
    public int rank;
    public String suit;
}
class CardComparator implements Comparator<Card>{
    @Override
    public int compare(Card o1, Card o2) {
        if(o1 == o2)
            return 0;
        if(o1 == null)
            return -1;
        if(o2 == null)
            return 1;
        return o1.rank - o2.rank;
    }
}

那么如何使用呢?
此时我们就需要实例化一个CardComparator比较器的对象,然后利用这个实例化之后的对象去调用这个方法,在方法中传入我们相比较的两个对象即可。

// 定义比较器对象
CardComparator cmptor = new CardComparator();
//p,q是两个Card类型的实例化对象
System.out.println(cmptor.compare(p, q));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值