栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java 基础知识点

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java 基础知识点

Java 基础知识点 一、equals实现原理

定义:通过某个特征值来判断两个对象是否“等价”,当这两个对象等价时,判断结果为true,否则结果为false。

  1. 默认源码 : 默认请情况下Object 对象做对象内存地址比较;

    public boolean equals(Object obj) {
        return (this == obj);
    }
  2. 重写equals逻辑 : 重写后对象进行值比较,更改比较条件

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return age == user.age &&
                id == user.id &&
                Objects.equals(name, user.name);
    }
二、== 对象比较原理

==比较的是2个对象的地址

三、重写equals为何要重写hashcode

重写equals为何要重写hashcode的文章多如繁星,每次看这都懂,过后就忘记,今日手工写点案例进行测试说为何重写equals为何要重写hashcode,废话不多说直接上代码。

  1. 不重写equals和hashcode方法

    案例:

    public class User {
        private String name;
        private int age;
        private long id;
        public User(String name, int age, long id) {
            this.name = name;
            this.age = age;
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public long getId() {
            return id;
        }
        public void setId(long id) {
            this.id = id;
        }
    //    @Override
    //    public boolean equals(Object o) {
    //        if (this == o) return true;
    //        if (o == null || getClass() != o.getClass()) return false;
    //        User user = (User) o;
    //        return age == user.age &&
    //                id == user.id &&
    //                Objects.equals(name, user.name);
    //    }
    //
    //    @Override
    //    public int hashCode() {
    //        return Objects.hash(name, age, id);
    //    }
    }
    public class JavaCoding {
    ​
        public static void main(String[] args) {
            User user1 = new User("A", 11, 1L);
            User user2 = new User("A", 11, 1L);
            System.out.println("equals result : " + user1.equals(user2));
            System.out.println("== result : " + (user1 == user2));
    ​
            Map map = new HashMap<>();
            map.put(user1, "111");
            map.put(user2, "222");
            System.out.println("map.get(user1) : " + map.get(user1));
            System.out.println("map.get(user2) : " + map.get(user2));
            map.forEach((key, val) -> {
                System.out.println(key + "  " + val);
            });
    ​
        }
    }

输出结果:

equals result : false

== result : false

map.get(user1) : 111

map.get(user2) : 222

com.example.coding.pojo.User@1d81eb93 222

com.example.coding.pojo.User@4e50df2e 111

案例分析:

当没有重写equals和hascode时,上述案例中的user1和user2是通过new关键字创建出的两个不同的对象,其引用地址也完全不相同,equals和==此时均为比较对象引用地址,所以输出均为false结果不相同。

而使用对象做map KEY时,会调用对象的hashcode方法分配存储位置地址,由于对象的引用地址不相同,所以hash后的值也不同,最终会存放在不同的位置上,因此输出时可以完整输出map中的两个元素

  1. 重写equals不重写hashcode方法

    public class User {
        private String name;
        private int age;
        private long id;
        public User(String name, int age, long id) {
            this.name = name;
            this.age = age;
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public long getId() {
            return id;
        }
        public void setId(long id) {
            this.id = id;
        }
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            User user = (User) o;
            return age == user.age &&
                    id == user.id &&
                    Objects.equals(name, user.name);
        }
        
    //    @Override
    //    public int hashCode() {
    //        return Objects.hash(name, age, id);
    //    }
    }
    public class JavaCoding {
    ​
        public static void main(String[] args) {
            User user1 = new User("A", 11, 1L);
            User user2 = new User("A", 11, 1L);
            System.out.println("equals result : " + user1.equals(user2));
            System.out.println("== result : " + (user1 == user2));
    ​
            Map map = new HashMap<>();
            map.put(user1, "111");
            map.put(user2, "222");
            System.out.println("map.get(user1) : " + map.get(user1));
            System.out.println("map.get(user2) : " + map.get(user2));
            map.forEach((key, val) -> {
                System.out.println(key + "  " + val);
            });
    ​
        }
    }

    输出结果:

    equals result : true

    == result : false

    map.get(user1) : 111

    map.get(user2) : 222

    com.example.coding.pojo.User@1d81eb93 222 com.example.coding.pojo.User@4e50df2e 111

    案例分析:

    1、由于重写equlas方法,因此对象做equals比较时实际是比较对象中元素的值,上述两个对象的值完全相同,所以为true

    2、== 由于是比较对象的栈中的引用地址,而对象是通过new的方式创建,因此地址是不相同的,所以为false

    3、而使用对象做map KEY时,会调用对象的hashcode方法分配存储位置地址,由于对象的引用地址不相同,所以hash后的值也不同,最终会存放在不同的位置上,因此输出时可以完整输出map中的两个元素

  2. 重写equals和hashcode方法

    public class User {
        private String name;
        private int age;
        private long id;
        public User(String name, int age, long id) {
            this.name = name;
            this.age = age;
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public long getId() {
            return id;
        }
        public void setId(long id) {
            this.id = id;
        }
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            User user = (User) o;
            return age == user.age &&
                    id == user.id &&
                    Objects.equals(name, user.name);
        }
    ​
        @Override
        public int hashCode() {
            return Objects.hash(name, age, id);
        }
    }
    public class JavaCoding {
    ​
        public static void main(String[] args) {
            User user1 = new User("A", 11, 1L);
            User user2 = new User("A", 11, 1L);
            System.out.println("equals result : " + user1.equals(user2));
            System.out.println("== result : " + (user1 == user2));
    ​
            Map map = new HashMap<>();
            map.put(user1, "111");
            map.put(user2, "222");
            System.out.println("map.get(user1) : " + map.get(user1));
            System.out.println("map.get(user2) : " + map.get(user2));
            map.forEach((key, val) -> {
                System.out.println(key + "  " + val);
            });
    ​
        }
    }

    输出结果:

    equals result : true

    == result : false

    map.get(user1) : 222

    map.get(user2) : 222

    com.example.coding.pojo.User@169b6 222

    案例分析:

    1、由于重写equlas方法,因此对象做equals比较时实际是比较对象中元素的值,上述两个对象的值完全相同,所以为true

    2、== 由于是比较对象的栈中的引用地址,而对象是通过new的方式创建,因此地址是不相同的,所以为false

    3、由于重写的了hashcode方法(实际对对象的数据进行hash),对象user1和user2中的数据完全相同,在map插入的时候两个对象hash出来的值也相同,因此后查询的user2和覆盖先查询的uesr1的value值,因此输出结果中会出现user2对应的map结果值222

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/606286.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号