java对象的比较主要有
- Object.equals
- Comparable
- Comparator
1.==和equals比较
p == q 表示的是 p 和 q 两个引用指向同一个对象
p.equals(q) 表示 p 指向的对象 和 q 指向的对象是否是值语义相等的(使用时需要进行覆写例如下面的程序判断两张扑克牌:)
public class Card {
public int rank; // 数值
public String suit; // 花色
public Card(int rank, String suit) {
this.rank = rank;
this.suit = suit;
}//构造函数
@Override
public boolean equals(Object o) {
if (this == 0)
{
return true;
}//如果指向同一个对象 返回true
if (o == null || !(o instanceof Card)) {
return false;
}//如果内容为空或者不是Card的对象 返回false
Card c = (Card)o;
return rank == c.rank && suit.equals(c.suit);
}
}
Card p = new Card(1, "♠");
Card q = new Card(1, "♠");
Card o = p;
p == o;// true
p == q; // false
p.equals(o); // true
p.equals(q); // true
2.Comparable<E>接口
public interface Comparable<E> {
// 返回值:
// < 0: 表示 this 指向的对象小于 o 指向的对象
// == 0: 表示 this 指向的对象等于 o 指向的对象
// > 0: 表示 this 指向的对象大于 o 指向的对象
int compareTo(E o); //比较方法
}
3.Comparator<E>接口
public interface Comparator<T> {
// 返回值:
// < 0: 表示 o1 指向的对象小于 o2 指向的对象
// == 0: 表示 o1 指向的对象等于 o2 指向的对象
// > 0: 表示 o1 指向的对象等于 o2 指向的对象
int compare(T o1, T o2);
}
4.Comparable与Comparator的区别
1.自然顺序(类直接实现接口)
p.compareTo(q);
2.非自然顺序:(定义一个比较器实现Comparator接口)
comparator名称=new类名();
名称.compareTo(p,q)
3.Comparable.compareTo需要进行重写,相当于你制定的规则所有排序都,可以按照这个来做。
4.comparator接口中的方法compare不需要进行重写,但需要重新写一个比较器通过它来调用compareTo
5.String和Integer中包含接口comparable所以他两为自然顺序(规定)
5.编写一个对人进行比较的程序(年龄为自然顺序)
import java.util.Comparator;
class PersonNameComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return o1.name.compareTo(o2.name);
}
}//定义了一个用名字作为排序准则的用来实现Comparator接口
// 实现非自然顺序排列
class PersonHeightComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return (int)((o1.height-o2.height)*100);
}
}//定义了一个用身高作为排序准则的用来实现Comparator接口
// 实现非自然顺序排列
//将double型转换为int型
class ComplexComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
if (o1.height < o2.height) {
return -1;
} else if (o1.height > o2.height) {
return 1;
}
if (o1.weight < o2.weight) {
return -1;
} else if (o1.weight > o2.weight){
return 1;
}
int r = o1.name.compareTo(o2.name);
if (r != 0) {
return r;
}
return o1.age - o2.age;
}
}//将所有方式的比较方法进行了整合
public class Person implements Comparable<Person> {//<>中存放的是比较的类型
public String name;//本身自带comparable借口 所以实现自然顺序
public int age;//自然顺序
public double height;
public double weight;
@Override
public int compareTo(Person o) {
//将此对象与指定对象(this指向的和o指向的)
//返回值为正数 负数 0;
//return age - o.age;//自己规定 在这我认为小的在前(年龄小的排前面)
if (age < o.age) {
return -1;
} else if (age == o.age) {
return 0;
} else
return 1;
}//compareTo需要进行重写 相当于你制定的规则 排序要按照这个来做
//而comparator接口中的方法compare不需要进行重写
// 但需要重新写一个比较器 通过它来调用compareTo
public static void main(String[] args) {
Person p = new Person();
Person q = new Person();
p.name = "Jin";
p.age = 28;
p.height = 1.78;
q.name = "JK";
q.age = 23;
q.height = 1.77;
int ret = p.compareTo(q);//自然顺序不用自定义比较器
if (ret < 0)
System.out.printf("%s小于%s", p.name, q.name);
else if (ret == 0)
System.out.printf("%s等于%s", p.name, q.name);
else
System.out.printf("%s大于%s", p.name, q.name);
System.out.println("===========================================");
Comparator<Person> comparator1 = new PersonNameComparator();//非自然顺序需要自己定义比较器
// 定义了一个属于comparator接口的对象
//再调用相关接口的比较方法
System.out.println("按照名字比较");
int s = comparator1.compare(p, q);
if (s < 0)
System.out.printf("%s小于%s", p.name, q.name);
else if (s == 0)
System.out.printf("%s等于%s", p.name, q.name);
else
System.out.printf("%s大于%s", p.name, q.name);
System.out.println("========================================");
Comparator<Person> comparator2 = new PersonHeightComparator();//非自然顺序需要自己定义比较器
// 定义了一个属于comparator接口的对象
//再调用相关接口的比较方法
System.out.println("按照身高比较");
int val = comparator2.compare(p, q);
if (val < 0)
System.out.printf("%s小于%s", p.name, q.name);
else if (val == 0)
System.out.printf("%s等于%s", p.name, q.name);
else
System.out.printf("%s大于%s", p.name, q.name);
}
}