java如何比较两个对象是否一样

位置:首页>文章>详情   分类: 教程分享 > Java教程   阅读(655)   2024-04-17 12:33:22

一、判断2个对象是否相等时用equals还是直接==

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;
    }

三、ArrayList去除重复对象的元素可以重写对象的hashcode方法和equls方法来进行去重,见下面代码

  实体对象:

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,



 

标签:
地址:https://www.leftso.com/article/320.html

相关阅读

ArrayList去除重复对象元素及list对象根据制定字段值排序
java基础编程中float/double类型的正确比较方法
java 面向对象编程,什么是面向对象,面向对象思想。本文将会以上帝对话的方式向你讲述面向对象的来由。为啥会有面向对象的出现。面向对象解决了那些问题。
Java编程中如何避免NullPointerException(空指针异常)
MultipartFile 对象创建,某些时候我们需要创建MultipartFile 对象,用于参数传递。这里讲解下如何创建MultipartFile 对象
本文主要讲解通过使用 Stream.concat() 方法 去合并两个stream,新的stream由原来的两个stream所有元素组成(相同元素会覆盖)
Java 8使用多个comparators进行集合分组排序
java json字符串转对象_json转换为java对象_ json字符串转对象数组
线程安全是像Java这样的语言/平台中的类的重要质量,我们经常在线程之间共享对象。由于缺乏线程安全性而导致的问题非常难以调试,因为它们零星且几乎不可能有意再现。你如何测试你的对象以确保它们是线程...
每个Java学习者都会遇到10 + 1个常见错误,java 初学者常见十大潜在错误