java中的基本数据类型判断是否相等,直接使用"=="就行了,相等返回true,否则,返回false。
但是java中的引用类型的对象比较变态,假设有两个引用对象obj1,obj2,
obj1==obj2 判断是obj1,obj2这两个引用变量是否相等,即它们所指向的对象是否为同一个对象。言外之意就是要求两个变量所指内存地址相等的时候,才能返回true,每个对象都有自己的一块内存,因此必须指向同一个对象才返回ture。
如果想要自定义两个对象(不是一个对象,即这两个对象分别有自己的一块内存)是否相等的规则,那么必须在对象的类定义中重写equals()方法,如果不重写equals()方法的话,默认的比较方式是比较两个对象是否为同一个对象。
在Java API中,有些类重写了equals()方法,它们的比较规则是:当且仅当该equals方法参数不是 null,两个变量的类型、内容都相同,则比较结果为true。这些类包括:String、Double、Float、Long、Integer、Short、Byte、、Boolean、BigDecimal、BigInteger等等,太多太多了,但是常见的就这些了,具体可以查看API中类的equals()方法,就知道了。
对象比较equls方法jdk源码为如下:
public boolean equals(Object obj) {
return (this == obj);
}
重写equals()方法的步骤一般如下:
1、先用“==”判断是否相等。
2、判断equals()方法的参数是否为null,如果为null,则返回false;因为当前对象不可能为null,如果为null,则不能调用其equals()方法,否则抛java.lang.NullPointerException异常。
3、当参数不为null,则如果两个对象的运行时类(通过getClass()获取)不相等,返回false,否则继续判断。
4、判断类的成员是否对应相等。往下就随意发挥了。
如下代码(直接重写了hashCode方法为后面排序使用):
@Override
public int hashCode() {
//重写hashcode
//return super.hashCode();
return (name + idNum).hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
if (!(obj instanceof Person)) {
return false;
}
Person person = (Person)obj;
//return super.equals(obj);
//如果this.name==null或者this.idNum==null会报错的,原因很简单就不多说了
return this.name.equals(person.getName()) && this.idNum.equals(person.getIdNum());
}
上面是重写的方法,这样2个对象的name和idNum字段就作为我的对象的hashcode作为对象的内存值存储,并且调取我重写的equls方法判断。
class CompareObj{
public static boolean contrastObj(Object obj1, Object obj2) {
if (obj1 == null || obj2 == null) {
return false;
}
//判断是不是同一个对象 此处对象是Person直接判断是否Person
if (!(obj1 instanceof Person) || !(obj2 instanceof Person)){
return false;
}
boolean flag = true;
Class clazz = obj1.getClass();
Field[] fields = clazz.getDeclaredFields();
try {
for (Field field : fields) {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), clazz);
Method method = propertyDescriptor.getReadMethod();
Object object1 = method.invoke(obj1);
Object object2 = method.invoke(obj2);
if (object1 == null || object2 == null) {
//此处千万不要直接 flag = false; break;注意看逻辑,如果都为空的话是返回true的
if (object1 == null && object2 != null) {
flag = false;
break;
} else if (object1 != null && object2 == null) {
flag = false;
break;
}
} else if (!object1.toString().equals(object2.toString())) {
flag = false;
break;
}
}
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return flag;
}
实体对象:
class Person{
private String name;
private String idNum;
private int age;
private int sex;
public Person(String name, String idNum, int age, int sex) {
this.name = name;
this.idNum = idNum;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIdNum() {
return idNum;
}
public void setIdNum(String idNum) {
this.idNum = idNum;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
@Override
public int hashCode() {
//重写hashcode
//return super.hashCode();
return (name + idNum).hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
if (!(obj instanceof Person)) {
return false;
}
Person person = (Person)obj;
//return super.equals(obj);
//如果this.name==null或者this.idNum==null会报错的,原因很简单就不多说了
return this.name.equals(person.getName()) && this.idNum.equals(person.getIdNum());
}
}
List<Person> list = new ArrayList<>();
Person person1 = new Person("test1", "88888", 20,10);
list.add(person1);
Person person2 = new Person("test1", "88888", 30,10);
list.add(person2);
Person person3 = new Person("test3", "3333", 22,11);
list.add(person3);
Person person4 = new Person("test4", "55555555", 10,11);
list.add(person4);
//去重
Set<Person> set = new HashSet<>();
//根据hashSet源码可以知道,set的add方法其实是根据hashMap的key去存储的,那么我们重写了person对象的hashcode方法后,对象根据name+idNum生产的hashcode相同时,
//map的key是唯一的,那么set的对应对象也就唯一了,做到了去重处理
set.addAll(list);
list.clear();
list.addAll(set);
System.out.println(list.size());
//list原有长度为4,被我们去重后长度变成3
List<Person> list = new ArrayList<>();
Person person1 = new Person("test1", "88888", 20,10);
list.add(person1);
Person person2 = new Person("test1", "88888", 30,10);
list.add(person2);
Person person3 = new Person("test3", "3333", 22,11);
list.add(person3);
Person person4 = new Person("test4", "55555555", 10,11);
list.add(person4);
//排序 使用集合自带方法排序(根据年龄排序,升序)
Collections.sort(list, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
if (o1.getAge() == 0 && o2.getAge() == 0) {
return 0;
}
return o1.getAge() > o2.getAge() ? 1 : -1;
}
});
for (Person person : list) {
System.out.print(person.getName());
System.out.print(",");
}
//输出顺序test4,test1,test3,
http://blog.xqlee.com/article/320.html