基本类型的比较VS引用类型的比较
数据类型的介绍
类型的比较,在Java中有两种数据类型,一种是基本数据类型,一中是引用类型。
基本数据类型包含一些我们常用的数据:
类型 | 类型名称 |
---|---|
byte | 字节型 |
int | 整型 |
char | 字符型 |
double | 浮点型 |
boolean | 布尔型 |
…… | …… |
而引用类型最常见的有:
类型 | 类型名称 |
---|---|
String | 字符串 |
Array | 数组 |
类、接口、数组、枚举、注解、泛型 | …… |
其中还有使用引用类型书写的基本数据类型:
基本数据类型 | 引用类型 |
---|---|
byte | Byte |
int | Integer |
char | Character |
double | Double |
boolean | Boolean |
…… | …… |
每个基本数据类型都有对应的引用类型,而他们作为基本数据类型比较时和引用类型比较时又存在着一点点差异。
基本数据类型的比较
基本数据类型之间可以直接比较,返回值是boolean型的最常用的就是==
比较运算符。
int a = 10;
int b = 20;
System.out.println(a==b);
//false
b = 10;
System.out.println(a==b);
//true
还有>
,<
,>=
,<=
和!=
这几种比较方法
int a = 20;
int b = 10;
System.out.println(a > b);
//true
System.out.println(a >= b);
//true
System.out.println(a != b);
//true
虽然基本数据类型我们已经使用不下上百次了,不过一些基本的引用数据类型也是需要理解和使用的。
引用数据类型的比较
引用类型也可以称之为对象,使用equal
来比较对象的大小,在字符串中我们倒是经常使用。
String s1 = "hello";
String s2 = "hello";
//使用 == 来比较
System.out.println(s1 == s2);
//true
//使用 equsl 来比较
System.out.println(s1.equals(s1));
//true
可以惊奇的发现!他们结果居然一样!这个是因为内存中有一个字符串常量池,其中会存储我们一些常用的字符串,就像上面代码中的hello
,在代码中如果需要这个字符串时,就相当于将这个字符串的地址引入过来,而使用==
对地址进行比较,发现地址是相同的。也就会输出true
.
String s1 = "hello";
//在内存中新开辟一块空间来存储 hello 字符串
String s2 = new String("hello");
//使用 == 来比较
System.out.println(s1 == s2);
//false
//使用 equsl 来比较
System.out.println(s1.equals(s1));
//true
新开辟的空间地址肯定和原来的地址不相同,所以这里会输出false
。
既然引用类型可以称之为对象,那么对于类对象之间的比较又是如何?
对象之间的比较
比如说对于一个猫咪的年龄进行比较是否可以直接使用比较运算符。
static class Cat {
String desc;//猫的品种
int age;//猫的年龄
public Cat(String desc, int age) {
this.desc = desc;
this.age = age;
}
}
public static void main(String[] args) {
Cat cat1 = new Cat("波斯猫", 3);
Cat cat2 = new Cat("短尾猫", 4);
Cat cat3 = cat1;
System.out.println(cat1 == cat2);//false
System.out.println(cat1 == cat3);//true
}
比较两个对象的地址是否相等,对于cat1
和cat2
,是不相等的,cat2
是新的一个对象自然地址不一样,所以会输出false
。
而cat3
是等于cat1
,表示这个指向cat1
这个对象,所以在比较时自然会相等,所以输出true
。
不过这个代码并没有按我们的想法去比较两个猫的年龄,可以看出无法使用比较运算符来比较。
使用Equal覆写基类
已知所有数据类型都是继承至Object
类,如果需要比较自定义类中的数据,使用equal
可以用于比较两个对象是否相等。
static class Cat {
String desc;//猫的品种
int age;//猫的年龄
public Cat(String desc, int age) {
this.desc = desc;
this.age = age;
}
//重写equals方法
@Override
public boolean equals(Object o){
if(this == o){
return true;
}
if(o == null || !(o instanceof Cat)){
return false;
}
Cat c = (Cat)o;
return age==c.age && desc == c.desc;
}
自己与自己比较,然后返回一个对象之间是否相等的值。
使用Comparable接口类来比较
Comparable
是JDK中提供的比较接口类,他可以用于比较泛型,也就是所有的数据类型,只需要你指定一个比较对象,这个比较器就会根据你提供的比较方法来比较两个数据。
使用Comparable中compareTo方法
public class Test {
static class Cat implements Comparable<Cat>{
String desc;//猫的品种
int age;//猫的年龄
public Cat(String desc, int age) {
this.desc = desc;
this.age = age;
}
//比较年龄
@Override
public int compareTo(Cat o) {
if(o==null){
return 1;
}
return age - o.age;
}
}
public static void main(String[] args) {
Cat cat1 = new Cat("波斯猫", 3);
Cat cat2 = new Cat("短尾猫", 4);
if(cat1.compareTo(cat2)==0){
System.out.println("一样大");
}else if(cat1.compareTo(cat2) > 0){
System.out.println("波斯猫大");
}else {
System.out.println("短尾猫大");
}
}
}
使用Comparator中Compare方法
源代码中compare。
static class ComparatorCat implements Comparator<Cat> {
//比较年龄
@Override
public int compare(Cat o1, Cat o2) {
return o1.age - o2.age;
}
}
public static void main(String[] args) {
Cat cat1 = new Cat("波斯猫", 3);
Cat cat2 = new Cat("短尾猫", 4);
ComparatorCat comparatorCat = new ComparatorCat();
int compare = comparatorCat.compare(cat1, cat2);
if(compare>0){
System.out.println("波斯猫大");
}else if(compare < 0){
System.out.println("短尾猫大");
}else {
System.out.println("一样大");
}
}
实现一个类实现这个比较器,创建对象来实现比较需要比较的数据。
引用类型之间三种比较方法之间的不同:
方法 | 使用方法 |
---|---|
Object.equals | 继承至Object,使用可以直接进行重写操作,只能比较相等,返回值Boolean |
Comparable.compareTo | 需要手动实现接口,每次使用都会排序,存在内部顺序 |
Comparator.compare | 实现一个比较器,对类的侵入性弱,代码侵入性强 |