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、首先我们先来创建一个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;
}
}
- 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);
}
- 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);
}
}
- 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、老规矩,使用刚才创建的Book(书)类
class Book {
public int price;
public String name;
public Book(int age, String name) {
this.price = age;
this.name = name;
}
}
- 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);//编译错误
}
}
- 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(优先级队列)中的比较。
来自小白的理解,如有错误,望各位大佬多多指正。