以前都是针对不同对象重写equals方法,面对大量不同值对象,需要重写很多,比较麻烦,而且重写equals方法大多也只是变量值进行比较。;
有看过别人写的一些,很多都很不理想。。So 一言不合就写个工具类
简单的逻辑
1、判断类型,基本类型、集合、对象分别处理;
2、基本类型直接判断,集合取出后再判断,对象则利用反射获取成员变量,递归取值;
3、没了
也许看起来两个对象判空的时候写的冗长,没有什么与或或者其他会让代码看起来简洁漂亮的写法;
但我觉得这样的朴素的写法可以让比较次数降到最低;
入口:传入两个值对象,并对属性进行分类
/**
* 同为空/都不为空:true
*/
public static boolean compareObject(Object head, Object tail) {
if (head == null) {
if (tail != null) {
return false;
} else {
return true;
}
} else {
if (tail == null) {
return false;
}
}
if (head.getClass() != tail.getClass()) {
return false;
}
if (head.equals(tail)) {
return true;
}
if (head.getClass() == String.class) {
return head.equals(tail);
} else if (head.getClass() == Integer.class) {
return (int) head == (int) tail;
} else if (head.getClass() == Boolean.class) {
return (boolean) head == (boolean) tail;
} else if (head.getClass() == Long.class) {
return (long) head == (long) tail;
} else if (head.getClass() == Double.class) {
return (double) head == (double) tail;
} else if (List.class.isAssignableFrom(head.getClass())) {
return compareList((List) head, (List) tail);
} else if (Map.class.isAssignableFrom(head.getClass())) {
return compareMap(head, tail);
}
Field[] fields = head.getClass().getDeclaredFields();
for (Field field : fields) {
// Class
cls = field.getType();
Object o1 = getFieldValue(head, field);
Object o2 = getFieldValue(tail, field);
boolean result = compareObject(o1, o2);
if (!result) {
return false;
}
continue;
}
return true;
}
获取field值
private static Object getFieldValue(Object bean, Field field) {
try {
field.setAccessible(true);
Object value = field.get(bean);
return value;
} catch (IllegalAccessException ace) {
ace.printStackTrace();
return null;
}
}
比较List :List中仍可存储类型的数据,所以使用compareObject方法来比较
private static boolean compareList(List head, List tail) {
if (head == null) {
if (tail == null || tail.isEmpty()) {
return true;
} else {
return false;
}
} else {
if (tail == null) {
return head.isEmpty();
}
}
if (head.isEmpty() && tail.isEmpty()) {
return true;
}
if (head.size() != tail.size()) {
return false;
}
for (int i = 0; i < head.size(); i++) {
boolean result = compareObject(head.get(i), tail.get(i));
if (!result) {
return false;
}
}
return true;
}
比较Map:Map中没有存储其他类型,均为基本类型,所以就偷懒直接equals比较了
private static boolean compareMap(Object head, Object tail) {
if (head == null) {
if (tail == null) {
return true;
} else {
boolean isEmpty = ((HashMap) tail).isEmpty();
if (isEmpty) {
return true;
} else {
return false;
}
}
} else {
if (tail == null) {
boolean isEmpty = ((HashMap) head).isEmpty();
if (isEmpty) {
return true;
} else {
return false;
}
}
}
HashMap
srcMap = (HashMap) head;
HashMap
tarMap = (HashMap) tail;
if (srcMap.keySet().isEmpty() && tarMap.keySet().isEmpty()) {
return true;
}
if (srcMap.keySet().size() != tarMap.keySet().size()) {
return false;
}
for (String key : srcMap.keySet()) {
if (!tarMap.containsKey(key)) {
return false;
}
Object vSrc = srcMap.get(key);
Object vTar = tarMap.get(key);
if (!vSrc.equals(vTar)) {
return false;
}
}
return true;
}
到这以及可以满足绝大部分的数据类型了,而且不论你数据多复杂,嵌套有多深。
没有short、char等,因为项目中没有,集合使用List、Map,其他也没有使用,所有就没有加入;
需要注意:
Object : true : Null && Null
Set : true : Null && Null , Empty && Empty , Empty && Null
下面是测试用,基本覆盖每个分支
public class TestEquals {
public static void main(String args[]) {
School school1 = getTestBean(0);
School school2 = getTestBean(1);
long start = System.currentTimeMillis();
boolean result = GeneralComparator.compareObject(school1, school2);
long end = System.currentTimeMillis();
System.out.print(result + " --- " + (end - start));
}
private static School getTestBean(int index) {
School school1 = new School();
school1.id = 3;
if (index == 1) {
// school1.id = 4;
}
ArrayList
teacher1 = new ArrayList<>();
Teacher t1 = new Teacher();
t1.setTeakcherTitle("ma");
if (index == 1) {
// t1.setTeakcherTitle("mas");
}
if (index == 1) {
// teacher1.add(t1);
}
teacher1.add(t1);
school1.teacherList = teacher1;
ArrayList
list = new ArrayList
();
list.add("list_1");
list.add("list_2");
list.add("list_4");
// if (index == 1) {
// list.add("list_4");
// }
school1.setSchsoolId(list);
//
HashMap
map1 = new HashMap
(); map1.put("ma2", "2"); map1.put("ma3", "22"); if (index == 1) { // map1.put("ma3", "2d2"); } school1.map = map1; ArrayList
> arrayMap = new ArrayList<>(); arrayMap.add(map1); if (index == 1) { // map1.put("ma2d","s2"); // arrayMap.add(map1); } school1.arrayMap = arrayMap; return school1; } } class School { public int id; private ArrayList
schsoolId; public HashMap
map; public ArrayList
teacherList; public ArrayList
> arrayMap; public ArrayList
getSchsoolId() { return schsoolId; } public void setSchsoolId(ArrayList
schsoolId) { this.schsoolId = schsoolId; } } class Teacher { public String teakcherTitle; public String getTeakcherTitle() { return teakcherTitle; } public void setTeakcherTitle(String teakcherTitle) { this.teakcherTitle = teakcherTitle; } }