java中的比较== < > Comparator和 Comparable

java原有数据类型的比较

## 1、基本数据类型的比较( < > ==)
话不多说,上代码:

    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println(a == b);//false
        System.out.println(a > b);//false
        System.out.println(a < b);//true

        char ch1 = 's';
        char ch2 = 'x';
        System.out.println(ch1 == ch2);//false
        System.out.println(ch1 < ch2);//true
        System.out.println(ch1 > ch2);//false

        //布尔类型只能判断相等与否
        boolean flg1 = false;
        boolean flg2 = true;
        System.out.println(flg1 == flg2);//false
    }

## 2、String类型的比较(equals)

	public static void main(String[] args) {
		//字符串的比较需要用equals
        //String 类型重写了equals方法
        String str1 = "abc";
        String str2 = "abc";
        String str3 = new String("abc");
        System.out.println(str1 == str2);//true
        System.out.println(str1.equals(str2));//true
        System.out.println(str1 == str3);//false
        System.out.println(str1.equals(str3));//true
    }

简单解释一下,在jvm内存中有栈,堆等。而堆上有常量池,当我们在主函数中创建String str1 = “abc”;时,str1存储在栈上,“abc"存储在堆的常量池中,当我们再次创建String str2 = “abc”;str2也是存储在栈上,jvm会先查看常量池中是否有"abc"这个字符串。如果有那么就让str2指向常量池中的"abc”,此时str1和str2保存的是同一个地址。所以我们用==判断时是true。因为str1和str2存储的是同一个地址。
在这里插入图片描述
而String中重写了Object类的equals方法,我们来看一下源码:

    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

大概判断方法就是将String类型辩词字符数组类型然后遍历字符数组进行比较。所以我们常常说字符串类型的比较是否相同,要使用equals方法而不是==。

因为equals方法比较的是字符串的内容是否相同,==比较的是存储的地址是否相同。

下面我们来看下String str3 = new String(“abc”);我们都知道在java中只要new那么就会在堆上产生一个对象。所以请看图:

在这里插入图片描述
我们发现str3指向的是new对象的地址,而对象指向的是常量池中的"abc",

这里对象指向"abc"和刚才的原理一样,当我们要创建字符串时,jvm首先会查看常量池中是否有这个字符串,如果有,那么将字符串的的地址给指向它的引用,如果没有再重新创建

所以str3保存的是对象的地址。当我们用==判断时,判断的是他们的地址,并不相等。而equals判断的是字符串的内容,所以结果是false。

对象的比较(自己创建的对象)

## 1、判断相等与否(equals)

  1. 1、首先我们先来创建一个Book(书)类
class Book {
    public int price;
    public String name;

    public Book(int age, String name) {
        this.price = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "age=" + price + ", name='" + name;
    }
}
  1. 2、在主函数中测试
public class Test {
    public static void main(String[] args) {
        Book book1 = new Book(98,"Lord of the flies");
        Book book2 = new Book(76,"Tuesdays with Morrie");
        Book book3 = new Book(98,"Lord of the flies");

        System.out.println(book1 == book3);//false
        System.out.println(book1.equals(book3));//false
    }
}

用==比较book1和book3,他们比较的还是地址。显然,他们指向的地址并不相同;
在这里插入图片描述
并且,当我们查看equals方法源码时:

    public boolean equals(Object obj) {
        return (this == obj);
    }
  1. 3、它们比较的还是地址,所以我们想要判断两本书是否相等时,需要在class Book中重写equals方法:
class Book {
    public int price;
    public String name;

    public Book(int age, String name) {
        this.price = age;
        this.name = name;
    }

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

	//重写的equals方法
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null) return false;
        Book book = (Book) o;
        return price == book.price &&
                this.name.equals(((Book) o).name);
    }
}
  1. 4、当我们再次测试时
public class Test {
    public static void main(String[] args) {
        Book book1 = new Book(98,"Lord of the flies");
        Book book2 = new Book(76,"Tuesdays with Morrie");
        Book book3 = new Book(98,"Lord of the flies");

        System.out.println(book1.equals(book3));//true
    }
}

## 2、判断大小(Comparator和Comparable)

  1. 1、老规矩,使用刚才创建的Book(书)类
class Book {
    public int price;
    public String name;

    public Book(int age, String name) {
        this.price = age;
        this.name = name;
    }
}
  1. 2、进行大小测试
public class Test {    
    public static void main(String[] args) {
        Book book1 = new Book(98,"Lord of the flies");
        Book book2 = new Book(76,"Tuesdays with Morrie");
        Book book3 = new Book(98,"Lord of the flies");

        System.out.println(book1 > book2);//编译错误
    }
}
  1. 3、编译器也不知道你要比较的是price还是书名的大小写,就算知道你比较的是书名大小写,你这< >也比较不了啊。所以我们需要实现Comparable接口或者创建一个Comparator比较器。
    我们用Comparator比较器来举例:
class NameComparator implements Comparator<Book> {

    @Override
    public int compare(Book o1, Book o2) {
        return o1.name.compareTo(o2.name);
    }
}
class PriceComparator implements Comparator<Book> {

    @Override
    public int compare(Book o1, Book o2) {
        return o1.price - o2.price;
    }
}

在compare方法中o1 和 o2的位置是可以换的,结果不一样但是谁比谁大还是一样的。
2. 4、我们再来测试

public class Test {
    public static void main(String[] args) {
        Book book1 = new Book(98,"Lord of the flies");
        Book book2 = new Book(76,"Tuesdays with Morrie");
        Book book3 = new Book(98,"Lord of the flies");

        PriceComparator pr = new PriceComparator();
        int x = pr.compare(book1,book2);
        System.out.println(x);//22

        NameComparator na = new NameComparator();
        int y = na.compare(book1,book2);
        System.out.println(y);//-8
    }
}

用price比较的结果是22,说明book1比book2贵;
用name比较的结果是-8,说明首字母book1小于book2;

暂且写到这里,后面我会再写一个Comparator 和Comparable的区别
还有PriorityQueue(优先级队列)中的比较。
来自小白的理解,如有错误,望各位大佬多多指正。

java历险记5(Comparator 和 Comparable的使用及区别)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值