精华内容
下载资源
问答
  • 2021-02-12 21:56:11

    在我们的实际开发中,通常会认为两个对象的内容相等时,则两个对象相等,equals返回true。对象内容不同,则返回false。

    可以总结为两种情况:

    1、类未复写equals方法,则使用equals方法比较两个对象时,相当于==比较,即两个对象的地址是否相等。地址相等,返回true,地址不相等,返回false。

    2、类复写equals方法,比较两个对象时,则走复写之后的判断方式。通常,我们会将equals复写成:当两个对象内容相同时,则equals返回true,内容不同时,返回false。

    注意:用“==”比较的是引用的地址,用equals比较的就是值。Object类中的equals方法定义为判断两个对象的地址是否相等(可以理解成是否是同一个对象),地址相等则认为是对象相等。这也就意味着,我们新建的所有类如果没有复写equals方法,那么判断两个对象是否相等时就等同于“==”,也就是两个对象的地址是否相等。

    问题:

    1、假设对象的属性不定,那重写equals时肯定无法穷尽所以字段;

    2、对象是第三方的引用,无法重写equals方法;

    解决方式:

    equals方法中使用反射获取所有字段的name和value,逐个对比;无法重写equal方法,就自己随便写一个,将要对比的对象作为入参丢进去;

    参考代码1:比较

    public StringBuilder compareContract(CreateContractSignInfoRequest sign, CreateContractSignInfoRequest existSign) {

    StringBuilder stringBuilder = new StringBuilder();

    try {

    Field[] fields = getAllFields(sign);

    for (int j = 0; j < fields.length; j++) {

    fields[j].setAccessible(true);

    // 字段值

    if (!fields[j].get(sign).equals(fields[j].get(existSign))) {

    stringBuilder.append(existSign.getUserName());

    stringBuilder.append(fields[j].getName() + "、");

    }

    }

    } catch (IllegalAccessException e) {

    e.printStackTrace();

    }

    return stringBuilder;

    }

    参考代码2:获取所有属性

    /**

    * 获取所有属性,包括父类

    *

    * @param object

    * @return

    */

    public Field[] getAllFields(Object object) {

    Class clazz = object.getClass();

    List fieldList = new ArrayList<>();

    while (clazz != null) {

    fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));

    clazz = clazz.getSuperclass();

    }

    Field[] fields = new Field[fieldList.size()];

    fieldList.toArray(fields);

    return fields;

    }

    反射扩展:

    (1)获取对象所属类的Class方法。

    Class c = Class.forName("包.类名称");

    (2)获得该类的所有Filed(不包括父类)。

    Field[] fields = c.getDeclaredFields();

    (3)将所有属性的访问权限设为true。

    因为JavaBean中所有的属性访问权限都是private,所以无法直接获得所有属性,因此我们必须获得其访问权限,通过下面的方法完成:

    setAccessible(true);

    (4)输出对象属性

    f.getField(对象名称);

    (5)获取字段名

    fields[j].getName()

    (6)获取字段值

    fields[j].get(obj)

    更多相关内容
  • Java比较两个对象中全部属性值是否相等

    万次阅读 多人点赞 2018-12-14 16:01:49
    Java比较两个对象中全部属性值是否相等 例如下述Java类: import java.io.Serializable; import java.util.List; public class Bean_Topology implements Serializable { private static final long ...

    例如下述Java类:

    import java.io.Serializable;
    import java.util.List;
    
    public class Bean_Topology implements Serializable {
    	private static final long serialVersionUID = 1L;
    	public static long getSerialversionuid() {
    		return serialVersionUID;
    	}
    
    	private Long topology_pk;
    
    	private String topology_id;
    
    	public String getTopology_id() {
    		return topology_id;
    	}
    
    	public void setTopology_id(String topology_id) {
    		this.topology_id = topology_id;
    	}
    
    	public Long getTopology_pk() {
    		return topology_pk;
    	}
    
    	public void setTopology_pk(Long topology_pk) {
    		this.topology_pk = topology_pk;
    	}
    
    	@Override
    	public String toString() {
    		return "当前拓扑的PK为:" + topology_pk + ",ID为:" + topology_id;
    	}
    }
    

    如下想判断下面两个对象中全部属性值是否一致时,有哪些办法呢?

    Bean_Topology topology1 = new Bean_Topology();
    	topology1.setTopology_id("1");
    
    Bean_Topology topology2 = new Bean_Topology();
    	topology2.setTopology_pk(1L);
    	topology2.setTopology_id("1");
    

    方法一:重写Bean_Topology的equals方法和hashcode方法,代码如下:

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
    		
        if (obj == null || getClass() != obj.getClass()) {
            return false;
         }
    
        Bean_Topology topology = (Bean_Topology) obj;
        if (topology_pk == null) {
            if (topology.topology_pk != null) {
                return false;
            } 
        }else if (!topology_pk.equals(topology.topology_pk)) {
            return false;	
        }
            
        if (topology_id == null) {
            if (topology.topology_id != null) {
                return false;
            } 
        }else if (!topology_id.equals(topology.topology_id)) {
            return false;	
        }
            
            return true;
        }
    	
        @Override
        public int hashCode() {
            return  topology_pk.hashCode()+topology_id.hashCode();
        }
    

    测试代码如下:

    if(topology1.equals(topology2)) {
    	System.out.println("对象1与对象2的属性值无差异。");
    }else {
    	System.out.println("对象1与对象2的属性值有差异。");	
    }
    

    输出结果为:

    对象1与对象2的属性值有差异。
    

    方法二:调用文章末尾的工具类,代码如下:

    Map<String, Map<String,Object>> resultMap=compareFields(topology1,topology2);
    int size=resultMap.size();
    if(size>0) {
        System.out.println("对象1与对象2的属性值有差异,差异结果如下:");
    		
        Iterator<String> it = resultMap.keySet().iterator();
        while(it.hasNext()) {
            String key=it.next();
            System.out.println("  "+key+"(oldValue:"+resultMap.get(key).get("oldValue")+",newValue:"+resultMap.get(key).get("newValue")+")");
            }	
    }else {
    	System.out.println("对象1与对象2的属性值无差异!");
    }
    

    输出结果为:

    对象1与对象2的属性值有差异,差异结果如下:
      topology_pk(oldValue:null,newValue:1)
    

    工具类如下:

    package com.sitech.modual.util.compare;
    
    import java.beans.Introspector;
    import java.beans.PropertyDescriptor;
    import java.lang.reflect.Method;
    import java.sql.Timestamp;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    import com.sitech.modual.bean.Bean_Link;
    import com.sitech.modual.bean.Bean_Topology;
    
    public class ClassCompareUtil {
    	/**
    	 * 比较两个实体属性值,返回一个boolean,true则表时两个对象中的属性值无差异
    	 * @param oldObject 进行属性比较的对象1
    	 * @param newObject 进行属性比较的对象2
    	 * @return 属性差异比较结果boolean
    	 */
    	public static boolean compareObject(Object oldObject, Object newObject) {
    		Map<String, Map<String,Object>> resultMap=compareFields(oldObject,newObject);
    		
    		if(resultMap.size()>0) {
    			return false;
    		}else {
    			return true;
    		}
    	}
    	
    	/**
    	 * 比较两个实体属性值,返回一个map以有差异的属性名为key,value为一个Map分别存oldObject,newObject此属性名的值
    	 * @param oldObject 进行属性比较的对象1
    	 * @param newObject 进行属性比较的对象2
    	 * @return 属性差异比较结果map
    	 */
    	@SuppressWarnings("rawtypes")
    	public static Map<String, Map<String,Object>> compareFields(Object oldObject, Object newObject) {
    		Map<String, Map<String, Object>> map = null;
    		
    		try{	
    			/**
    			 * 只有两个对象都是同一类型的才有可比性
    			 */
    			if (oldObject.getClass() == newObject.getClass()) {
    				map = new HashMap<String, Map<String,Object>>();
    				
    				Class clazz = oldObject.getClass();
    				//获取object的所有属性
    				PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz,Object.class).getPropertyDescriptors();
    				
    				for (PropertyDescriptor pd : pds) {
    					//遍历获取属性名
    					String name = pd.getName();
    					
    					//获取属性的get方法
    					Method readMethod = pd.getReadMethod();
    					
    					// 在oldObject上调用get方法等同于获得oldObject的属性值
    					Object oldValue = readMethod.invoke(oldObject);
    					// 在newObject上调用get方法等同于获得newObject的属性值
    					Object newValue = readMethod.invoke(newObject);
    					
    					if(oldValue instanceof List){
    						continue;
    					}
    					
    					if(newValue instanceof List){
    						continue;
    					}
    					
    					if(oldValue instanceof Timestamp){
    						oldValue = new Date(((Timestamp) oldValue).getTime());
    					}
    					
    					if(newValue instanceof Timestamp){
    						newValue = new Date(((Timestamp) newValue).getTime());
    					}
    					
    					if(oldValue == null && newValue == null){
    						continue;
    					}else if(oldValue == null && newValue != null){
    						Map<String,Object> valueMap = new HashMap<String,Object>();
    							valueMap.put("oldValue",oldValue);
    							valueMap.put("newValue",newValue);
    						
    						map.put(name, valueMap);
    						
    						continue;
    					}
    					
    					if (!oldValue.equals(newValue)) {// 比较这两个值是否相等,不等就可以放入map了
    						Map<String,Object> valueMap = new HashMap<String,Object>();
    							valueMap.put("oldValue",oldValue);
    							valueMap.put("newValue",newValue);
    						
    						map.put(name, valueMap);
    					}
    				}
    			}
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    		
    		return map;
    	}
    
    }
    

    注意:本工具类不适用于比较包含List,Map等类的Class。

    展开全文
  • Java比较两个对象并获取其中不相等的字段

    万次阅读 多人点赞 2019-03-24 23:22:41
    在工作中,我们经常会遇到这样的需求——比较两个对象是否相等,如果不相等的话,取出不相等的字段。 以下这些场景都需要我们对一个对象进行比较: 数据比对 做单元测试断言对象是否相等 前端要求对不相等的字段...

    原创文章,转载请注明出处:https://blog.csdn.net/dadiyang/article/details/88782898

    写在前面

    在工作中,我们经常会遇到这样的需求——比较两个对象是否相等,如果不相等的话,取出不相等的字段

    以下这些场景都需要我们对一个对象进行比较:

    • 数据比对
    • 单元测试断言对象是否相等
    • 前端要求对不相等的字段进行高亮显示

    这种需求其实是非常简单的,但是如何优雅地解决这一类需求呢?

    通常的做法是重写对象的 equals 方法。但是重写 equals 方法有很多缺点,例如:

    • 每次对象属性有变更,一定要记得再重写(放心,你一定会忘记的
    • 每个对象只能有一个 equals 方法,但是可能你会需要不同的比对规则
    • 只能对比两个对象是否相等,无法具体知道哪个属性不等
    • 自动生成的 equals 方法无法基于 getter 方法进行比对
    • 对象来自第三方依赖,无法重写 equals 方法

    因此,实现一个通用的比对器可以减少很多不必要的麻烦,帮助我们很好地完成这一类的需求

    缘起

    我是在做数据同步的时候有这个需求,我要将数据库的数据通过一定的规则导入到 ES 中,导入完成之后,如何比对两边的数据是否一致呢?这时候一个好用的比对器就是我非常好的帮手。

    另外,我在做单元测试的时候发现,经常会需要将被测方法的返回值和期望的结果做 assertEquals 断言这时这个比对器也非常有帮助。我发现很多同事经常会遇到类似的需求。

    于是,我找时间自己实现了一下。

    实现

    使用反射对传入的对象进行比对,提供了基于字段的比较器和基于 Getter 方法的对比器,并且充分考虑扩展性,使用者可以重写字段的比对规则。功能相对简单,代码实现也不难,而且做了很多注释,具体实现可以直接查看源码。

    项目地址:https://github.com/dadiyang/equator

    UML图:
    Equator UML 图

    使用方法

    因为已经上传到了 maven 仓库中,我们使用非常方便:

    1. 添加 maven 依赖
    <dependency>
        <groupId>com.github.dadiyang</groupId>
        <artifactId>equator</artifactId>
        <version>1.0.3</version>
    </dependency>
    
    1. 初始化并调用方法
    Equator equator = new GetterBaseEquator();
    User user1 = new User(...);
    User user2 = new User(...);
    // 判断属性是否完全相等
    equator.isEquals(user1, user2);
    // 获取不同的属性
    List<FieldInfo> diff = equator.getDiffFields(user1, user2);
    

    扩展

    我们可以通过继承并重写 isFieldEquals 方法自定义比对规则,例如我们在做单元测试的时候,对于 Date 类型的字段的比对,通常数据库不保存毫秒数,而我们 new 出来的 Date 对象则包含了毫秒数,因此我们在对包含 Date 类型字段的对象做比对的时候需要忽略日期的毫秒数。这时就可以通过重写isFieldEquals 方法来自定义了:

    /**
     * 日期在数据库不保存毫秒数,因此需要特殊处理,比对时间时,忽略毫秒数
     *
     * @author dadiyang
     * @date 2019/3/23
     */
    public class MmInsensitiveEquator extends GetterBaseEquator {
        @Override
        protected boolean isFieldEquals(FieldInfo fieldInfo) {
            if (fieldInfo.getFirstVal() instanceof Date) {
                Date first = (Date) fieldInfo.getFirstVal();
                Date second = (Date) fieldInfo.getSecondVal();
                if (Objects.equals(first, second)) {
                    return true;
                }
                // 忽略毫秒数
                return Objects.equals(Math.round(first.getTime() / 1000), Math.round(second.getTime() / 1000));
            }
            return super.isFieldEquals(fieldInfo);
        }
    }
    

    后记

    对象比对是一个非常小的需求,通常我们只会写一个工具类来完成。但是写一个工具类在各个项目间随处拷贝,非常不优雅,给整个团队带来很多不必要的维护成本。而且扩展性比较差,有任何差异就需要写很多代码去实现。

    这时,如果我们从具体解决某一个需求的视角上升到解决一类需求,那么就能想出更加通用和优雅的解决方案了。一个个具体的需求是无穷无尽的,以有限的人生去解决无限的需求,殆矣;但是将它们归类之后,我们会发现,需求的种类是有限的

    因此解决一类一类问题,能让我们摆脱无穷无尽的重复劳动,少加点班,多点时间陪陪家人哦。

    展开全文
  • Java比较两个对象的属性值是否相等 import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.sql.Timestamp; import java.util.*; /** * 比较两个...

    Java比较两个对象的属性值是否相等

    import java.beans.Introspector;
    import java.beans.PropertyDescriptor;
    import java.lang.reflect.Method;
    import java.sql.Timestamp;
    import java.util.*;
    
    /**
     * 比较两个对象的属性值
     */
    public class CompareUtil {
    
        /**
         * 比较两个实体属性值,返回一个boolean,true则表时两个对象中的属性值无差异
         * @param oldObject 进行属性比较的对象1
         * @param newObject 进行属性比较的对象2
         * @return 属性差异比较结果boolean
         */
        public static boolean compareObject(Object oldObject, Object newObject) {
            Map<String, List<Object>> resultMap=compareFields(oldObject,newObject,null);
    
            if(resultMap.size()>0) {
                return false;
            }else {
                return true;
            }
        }
    
        /**
         * 比较两个实体属性值,返回一个map以有差异的属性名为key,value为一个Map分别存oldObject,newObject此属性名的值
         * @param obj1 进行属性比较的对象1
         * @param obj2 进行属性比较的对象2
         * @param ignoreArr 忽略比较的字段
         * @return 属性差异比较结果map
         */
        @SuppressWarnings("rawtypes")
        public static Map<String, List<Object>> compareFields(Object obj1, Object obj2, String[] ignoreArr) {
            try{
                Map<String, List<Object>> map = new HashMap<String, List<Object>>();
                List<String> ignoreList = null;
                if(ignoreArr != null && ignoreArr.length > 0){
                    // array转化为list
                    ignoreList = Arrays.asList(ignoreArr);
                }
                if (obj1.getClass() == obj2.getClass()) {// 只有两个对象都是同一类型的才有可比性
                    Class clazz = obj1.getClass();
                    // 获取object的属性描述
                    PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz,
                            Object.class).getPropertyDescriptors();
                    for (PropertyDescriptor pd : pds) {// 这里就是所有的属性了
                        String name = pd.getName();// 属性名
                        if(ignoreList != null && ignoreList.contains(name)){// 如果当前属性选择忽略比较,跳到下一次循环
                            continue;
                        }
                        Method readMethod = pd.getReadMethod();// get方法
                        // 在obj1上调用get方法等同于获得obj1的属性值
                        Object o1 = readMethod.invoke(obj1);
                        // 在obj2上调用get方法等同于获得obj2的属性值
                        Object o2 = readMethod.invoke(obj2);
                        if(o1 instanceof Timestamp){
                            o1 = new Date(((Timestamp) o1).getTime());
                        }
                        if(o2 instanceof Timestamp){
                            o2 = new Date(((Timestamp) o2).getTime());
                        }
                        if(o1 == null && o2 == null){
                            continue;
                        }else if(o1 == null && o2 != null){
                            List<Object> list = new ArrayList<Object>();
                            list.add(o1);
                            list.add(o2);
                            map.put(name, list);
                            continue;
                        }
                        if (!o1.equals(o2)) {// 比较这两个值是否相等,不等就可以放入map了
                            List<Object> list = new ArrayList<Object>();
                            list.add(o1);
                            list.add(o2);
                            map.put(name, list);
                        }
                    }
                }
                return map;
            }catch(Exception e){
                e.printStackTrace();
                return null;
            }
        }
    }
    
    

    如有用,请留下你的足迹~

    展开全文
  • Java编程经验---比较两个List对象差异

    千次阅读 2020-06-30 23:40:47
    Java编程经验---比较两个List对象差异问题引入解决问题简化模型 问题引入 如何比较两个List对象的差异,这个问题来源于我最近正在开发的新系统中的一个细节。大致情况就是,从数据库中的一个视图A向另一个数据库的...
  • 需求:比较两个相同的对象,得到不同的属性值的属性和属性值,后面才是重点:对像里面包含其他的对象,也要拿出来,例如:两个user对象,user里面包含部门,如果两个user下面的部门不一致,要得到分别的部门名称,...
  • 通常我们会比较基本类型、引用类型、数组等是否相等,很少会 比较对象的Class实例对象是否相等,那么class实例对象如何比较相等呢? 可以使用“==”比较是否相等 obj.getClass() == ClassEqualTest.class 可以...
  • Java中如何判断两个对象是否相等

    千次阅读 2020-03-27 16:16:18
    如何判断两个对象相等,这个问题实际上可以看做是如何...
  • java中如何比较两个对象

    千次阅读 2018-11-22 22:32:14
    java中我们比较个对象是否为同一个对象的时候,使用 “==”,比如当我们比较两个object对象的时候,这个时候就可以用“==”,此时调用equals方法,它的内部实现也是“==”。 但当我们需要比较对象里面的基本...
  • 在使用数据库以及做详细的权限控制的时候,遇到要比较两个对象的情况,获得两个对象是否相同以及有那些字段被修改了,以判断用户是否有权限修改对象。apache commons提供的只有collections的对比,因此,本文利用...
  • 假设现在有需求如下:比较2个相同类型的不同对象,找到这2个对象的不同的地方,并展示记录一下。当然说的是相互对应的属性啦。 带着这个需求,看下面的例子。(我写代码的都不嫌弃长,你看代码的就也别嫌弃咯。) ...
  • import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class CompareObejct { private CompareStatus status; /** * 之前原始的值 */ ...
  • 实际开发中,存在比较两个对象,需要校验某些字段是否相同,如果不同,需返回属性名称和属性值对比结果 比较笨的办法就是,对两个对象需要判断的属性一一进行对比,如果只有几个属性值需要对比,可以满足,但是字段...
  • * Description: 判断两个对象的各个属性是否相同 * Param: isUpdate为true,表示对原有属性值进行覆盖更改,为false,则只增加原来没有的属性值,原来有的属性值不进行更改 * @throws IllegalAccessException  ...
  • } } 转换对象之间属性的方法 /** * 判断某个类是否存在某个属性 * @param t * @param fieldName * @return */ public static Boolean hasField(Class t,String fieldName){ Field[] declaredFields = t....
  • package com.cdc.console.controller;import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method;public class Test<T> { public String contrastObj(Object oldBe
  • JAVA两个对象属性合并

    万次阅读 2017-12-26 14:06:58
    import java.lang.reflect.Field; public class CombineBeans ... * @Description: 该方法是用于相同对象不同属性值的合并,如果两个相同对象中同一属性都有值, * 那么sourceBean中的值会覆盖tagetBean重点的值...
  • Java中如何判断两个对象是否相等(Java equals and ==)

    万次阅读 多人点赞 2017-12-15 02:16:13
    如何判断两个对象相等,这个问题实际上可以看做是如何对equals方法和hashcode方法的理解。 从以下几个点来理解equals和hashCode方法: 1、equals的作用及与==的区别。 2、hashcode的作用及与equals的关系。 ...
  • java判断两个对象是否是同一个对象

    万次阅读 2019-02-26 14:57:44
    比较两个对象是否相等,主要通过equals()和hashCode() equals()方法 hashCode()方法 equals()和hashCode()在hashSet中使用 一、equals() equals()是Object中的方法,比较的对象的内存地址(如图一)...
  • jsonArray array1 = [{"award_number":1,"start_time":"2017-12-04 17:17:35","end_time":"2017-12-09 17:17:39"},{"award_number":2,"start_time":"2017-12-09 17:17:35","end_time":"2017-12-12 17:17:39"},{...
  • 本文实现了比较两个List之间的差异,包括获取两List的差集,交集,并集(不去重)和 并集(去重)的API解法和优化解法的解决方案,并根据实际业务场景实现业务需求。
  • 如何判断两个Class对象是否相同 在JVM中表示两个class对象是否为同一个类存在两个必要条件: 类的完整类名必须一致,包括包名。 加载这个类的ClassLoader(指ClassLoader实例对象)必须相同。 换句话说,在JVM...
  • java比较两个map是否相同

    千次阅读 2021-03-24 11:48:24
    结论对于所有继承于AbstractMap的map类(基本上jdk中的map都继承了),直接使用Map.equals()即可源码解析AbstractMap重写了equals方法,保证对两个相同内容的map调用equals比较结果为真,源码如下public boolean equals...
  • java两个对象相同字段复制

    万次阅读 2019-01-24 09:42:19
    将user和userInfo拥有相同字段的值复制到userInfo对象中(如果user和userInfo间存在名称不相同的属性,则BeanUtils不对这些属性进行处理,需要手动处理) import org.springframework.beans.BeanUtils ...
  • Java 查找两个集合中的相同元素和不同元素 假设有这个集合, List<Category> metaCategs , 只要categId 在下面数组中,就从metaCategs中移除 Integer[] removeCategIds =ne...
  • java合并json对象,对象是ECharts里的Option 如 json1 {"title": {"textStyle": {"color": "1111","decoration": "2222"}}} json2 {"title": {"textStyle": {"color": "aaaa","color2": "bbbb"}}} 想得到的结果 {...
  • 2个不同对象,属性名不一样,不用get/set方法,怎么将一个对象中的属性赋值到另一个对象的属性中 对象内有几十个属性,如何用最少的代码实现
  • JAVA比较两个字符串日期或者Date日期的大小 compareTo关键字的使用 compareTo() 方法用于将 Number 对象与方法的参数进行比较。可用于比较 Byte, Long, Integer等。 该方法用于两个相同数据类型的比较两个不同类型...
  • Java中,时不时我们会把两个对象进行,然而得到的结果却不是我们想的结果,这是怎么回事呢? 一、两种形式的比较比较时,我们要弄清楚是哪一种比较。  1.值类型比较  即内容相同,我们就认为是相等的。比如...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,194,354
精华内容 877,741
关键字:

java比较两个对象内容

java 订阅