目录
一、Java中比较的分类
在Java中,我们一般分为两种比较类型, 基本类型的比较和引用类型的比较
二、基本类型的比较
Java有八大基本类型 分别是:
- 整型 : byte short int long
- 浮点型: float double
- 字符型: char
- 布尔类型:boolean
java中对于基本类型的比较通常使用比较运算符 == 进行比较 ==比较基本类型是比较值是否相等,比较引用类型是比较==两边的地址是否相等
一、==运算符
public static void main(String[] args) {
int a=6;
int b=6;
System.out.println(a==b);
String s=new String("hello world");
String p=new String("hello world");
System.out.println(s==p);
String d="hello world";
String f="hello world";
System.out.println(d==f);
}
由上图我们发现中间的结果为false ,这是因为new会新在堆中开辟一个地址,导致两个地址不一样;
最后的结果是ture 因为d在使用完后会存入常量池中,f再使用的时候会先在常量池中寻找,寻找到了就直接使用常量池中的地址
三、引用类型的比较
一、equals运算符
equals()方法只能用来比较两个对象的地址是否相同,子类中往往重写了该方法,用于判断类容是否相同,比如Integer、String等
class Animal{
public int age;
public String name;
public Animal(int age,String name){
this.age=age;
this.name=name;
}
}
public class Main {
public static void main(String[] args) {
Animal dog=new Animal(3,"qiuqiu");
Animal cat=new Animal(3,"qiuqiu");
System.out.println(dog.equals(cat));
}
}
我们接下来将代码进行覆写
import java.util.Objects;
class Animal{
public int age;
public String name;
public Animal(int age,String name){
this.age=age;
this.name=name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Animal animal = (Animal) o;
return age == animal.age && Objects.equals(name, animal.name);
}
@Override
public int hashCode() {
return Objects.hash(age, name);
}
}
public class Main {
public static void main(String[] args) {
Animal dog=new Animal(3,"qiuqiu");
Animal cat=new Animal(3,"qiuqiu");
System.out.println(dog.equals(cat));
}
}
二、基于Comparable接口类的比较
我们接下来实现Comparable接口,重写CompareTo方法
import java.util.Comparator;
import java.util.Objects;
class Animal implements Comparable<Animal> {
public int age;
public String name;
public Animal(int age,String name){
this.age=age;
this.name=name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Animal animal = (Animal) o;
return age == animal.age && Objects.equals(name, animal.name);
}
@Override
public int hashCode() {
return Objects.hash(age, name);
}
@Override
public int compareTo(Animal o) {
return this.age - o.age;
}
}
public class Main {
public static void main(String[] args) {
Animal dog=new Animal(3,"qiuqiu");
Animal cat=new Animal(3,"qiuqiu");
System.out.println(dog.compareTo(cat));
}
}
谁调用compareTo方法谁就是this.
被调用的就是compareTo里的参数o
如果返回值>0 就说明主调的对象大于被调的对象
如果返回值<0 就说明主调的对象小于被调的对象
如果返回值=0 就说明两个对象相等
当然,这种方法的缺点就是不灵活,比较的方式已经固定死了,我们通常使用下面这种定义比较器的方法
三、自己定义比较器,实现Comparator接口
方法:自己定义比较器,实现Comparator接口,重写compara方法,相比于上面的方法,对比较的类的侵入性弱
import java.util.Comparator;
import java.util.Objects;
class Animal implements Comparable<Animal> {
public int age;
public String name;
public Animal(int age,String name){
this.age=age;
this.name=name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Animal animal = (Animal) o;
return age == animal.age && Objects.equals(name, animal.name);
}
@Override
public int hashCode() {
return Objects.hash(age, name);
}
@Override
public int compareTo(Animal o) {
return this.age - o.age;
}
}
//姓名比较器
class Name implements Comparator<Animal>{
@Override
public int compare(Animal o1, Animal o2) {
return o1.name.compareTo(o2.name);
}
}
//年龄比较器
class Age implements Comparator<Animal>{
@Override
public int compare(Animal o1, Animal o2) {
return o1.age-o2.age;
}
}
public class Main {
public static void main(String[] args) {
Animal dog=new Animal(4,"wangwang");
Animal cat=new Animal(2,"miaomiao");
Name name = new Name();
Age age = new Age();
System.out.println(name.compare(dog,cat));
System.out.println(age.compare(dog,cat));
}
}
- 返回值< 0: 表示 o1 指向的对象小于 o2 指向的对象
- 返回值== 0: 表示 o1 指向的对象等于 o2 指向的对象
- 返回值> 0: 表示 o1 指向的对象等于 o2 指向的对象
四、总结对比三种比较
覆写的方法 | 说明 |
Object.equals | 因为所有类都是继承自 Object 的,所以直接覆写即可,不过只能比较相等与否 |
Comparable.compareTo | 要手动实现接口,代码侵入性强,不灵活 |
Comparator.compare | 需要实现一个比较器对象,对比较的类的侵入性弱,对算法实现侵入性强 |
如有错误还请指出,欢迎阅读