• ==和equals


    好人卡

    短暂的周末过去了,周一李大明白和诸葛十三依旧是最早到公司的。

    然后两个人进行了一段有趣的对话。

    李:周末干啥啦

    十三:看会儿书,看会儿小姐姐视频。

    李:还挺充实,没有出去转转呀。

    十三:没有,在家呆着多舒服。

    李:哈哈,你说的没毛病。

    十三:你呢,出去玩儿了吗

    李:我去领了一张卡片。

    十三:办银行卡啦?

    李:没有,领了一张好人卡。

    十三:哦啊,明白了。

    李:还得是我十三哥呀,啥都明白。

    十三:我可是卡片专家,看我抽屉,那么多卡片呢。

    李:哈哈,你可别出去跟人说你有很多小卡片,容易误会。也就我知道你那是外卖卡片,别人可不这么认为。

    十三:管别人怎么想呢,你要活成你自己的样子。

    李:对,十三哥说的是。

    李:十三哥,问你个问题。

    十三:你说

    李:你说,我的朋友、同事、家人,也给我介绍了好几个相亲对象了,为啥好些人都看不上我呢。

    十三:子非鱼焉知鱼之乐,我又不是她们,我也搞不清楚。

    李:你三体人,不懂我们人类,以后怎么统治我们? 没有梦想了吗

    十三:害,那我就简单给你分析分析,仅供参考。

    李:且说无妨。

    十三:无非是钱、貌

    钱:你以及你家人的房、车、薪资、工作是否稳定。

    貌:是否干干净净,这句话的意思就是是否长得像肖战。

    性格:性格这点你一定要注意了,不是说性格好就能找到对象,如过是这样的话,你也早就脱单了。

    一般说性格好,是指你要认同她所认同的。比如她认为地铁看短视频外放是一件正确的事,这个时候你就不能说,地铁规定不能外放。看似你是正确的,其实在她看来,你就是多管闲事。

    李:嗯。认同你的说法,但是不认同她们做法。

    李:很滑稽。

    十三:你们人类就这样,每个人都会活成自己讨厌的样子。平日里的道德一旦到了自己身上,那就是你多管闲事。

    李:也是,有时候不能怪别人,也正是有了这些不同,才有了这丰富多彩的大千世界。

    十三:是的,还是我们三体人好,不像你们,那么虚伪。

    李:你可别说了,我们顶多是害人,你们是想直接害人类。

    李:如果可以用程序来匹配两个人是否合适多好。

    以下内容纯属虚构:

    假设自己跟自己定义为匹配,也就是说你跟你是可以在一起的(除非精神分裂,否则这点儿已经是实时)

    其次,一男一女,2人薪资相差30%以内,男士必须有房、有车,两人性格匹配度80%以上。就可以匹配到一起。

    很好玩的代码

    package test;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * @author 木子的昼夜编程
     */
    public class Find {
        public static void main(String[] args) {
            MyPerson p01 = new MyPerson();
            p01.gender = '男';
            p01.hashCar = true;
            p01.hasHouse =true;
            p01.salary = 10000;
            p01.natures = Arrays.asList(MyPerson.N1,MyPerson.N3,MyPerson.N5,MyPerson.N7,MyPerson.N8);
    
            MyPerson p02 = new MyPerson();
            p02.gender = '男';
            p02.hashCar = true;
            p02.hasHouse =false;
            p02.salary = 10000;
            p02.natures = Arrays.asList(MyPerson.N1,MyPerson.N3,MyPerson.N5,MyPerson.N7,MyPerson.N8);
    
            MyPerson p03 = new MyPerson();
            p03.gender = '女';
            p03.hashCar = false;
            p03.hasHouse = true;
            p03.salary = 10000;
            p03.natures = Arrays.asList(MyPerson.N2,MyPerson.N4,MyPerson.N5,MyPerson.N7,MyPerson.N8);
    
            MyPerson p04 = new MyPerson();
            p04.gender = '女';
            p04.hashCar = false;
            p04.hasHouse = true;
            p04.salary = 7800;
            p04.natures = Arrays.asList(MyPerson.N3,MyPerson.N4,MyPerson.N5,MyPerson.N7,MyPerson.N8);
    
            // 自己跟自己
            System.out.println("1:"+ifMatch(p01, p01));
            // 男-男
            System.out.println("2:"+ifMatch(p01, p02));
            // 性格 1,3,5,7,8  《-》 2,4,5,7,8
            System.out.println("3:"+ifMatch(p01, p03));
            // 可以匹配
            System.out.println("4:"+ifMatch(p01, p04));
            // 没房
            System.out.println("5:"+ifMatch(p02, p03));
            // 没房
            System.out.println("6:"+ifMatch(p02, p04));
        }
    
        public static  String ifMatch(MyPerson p1, MyPerson p2){
            // 1. 自己跟自己
            if (p1 == p2) {
                return "自己跟自己匹配,单着一辈子吧";
            }
            // 2. 性别校验
            if (p1.gender == p2.gender) {
                return "性别有问题呀!";
            }
            // 3.计算薪资差值
            double salary01 = p1.salary;
            double salary02 = p2.salary;
            // 3.1 计算差值
            double diff = Math.abs(salary02 - salary01);
            // 3.2 获取薪资小的值
            double small = Math.min(salary01, salary02);
            // 3.3 计算差值比例  不能超过0.3
            double v = diff / small;
            if (v > 0.3) {
                return "薪资差多了,可能会有一方看不上另一方";
            }
            // 4. 看男生是否有房、有车
            MyPerson boy = p1.gender == '男' ? p1 : p2;
            if(!boy.hasHouse || !boy.hashCar) {
                return "不管你没房还是没车,没一个都不行";
            }
            // 5. 性格匹配 必须超过80%
            if (p1.natures == null || p1.natures.size() == 0
                    || p2.natures == null || p2.natures.size() ==0 ) {
                return "有一个人可能是个布娃娃,还是找个真人吧";
            }
            // 5.1 求交集 为了不影响之前对象属性 所以复制一份新的进行比较
            List<String> list01 = new ArrayList<>(p1.natures);
            List<String> list02 = new ArrayList<>(p2.natures);
            list01.retainAll(list02);
            // 5.2 计算比例 按照一般惯例我们需要使用Bigdecimal 这里就直接使用double了,不需要那么精确。
            int count = list01.size();
            double bl01 = Double.valueOf(count) / Double.valueOf(p1.natures.size());
            double bl02 = Double.valueOf(count) / Double.valueOf(p2.natures.size());
            if (bl01 < 0.8 || bl02 < 0.8) {
                return "性格匹配度小于80%";
            }
            return "匹配值不错,可以试试";
        }
    }
    
    class MyPerson{
        // 定义几种性格
        public static final String N1 = "孝顺";
        public static final String N2 = "喜欢读书";
        public static final String N3 = "喜欢运动";
        public static final String N4 = "喜欢历史";
        public static final String N5 = "喜欢哲学";
        public static final String N6 = "认为公共场所抽烟是不文明行为";
        public static final String N7 = "认为随地吐痰是不文明行为";
        public static final String N8 = "认为地铁视频外放是不文明行为";
        // 男女
        char gender;
        // 收入
        double salary;
        // 是否有房
        boolean hasHouse;
        // 是否有车
        boolean hashCar;
        // 性格
        List<String> natures;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120

    输出:

    在这里插入图片描述

    十三:你这还需要一个专门的方法ifMatch 来进行辨别,两个人是否合适。是不是可以直接写到equals方法中? 返回true就是合适 ,返回false就是不合适。

    李:这样吗

    package test;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Objects;
    
    /**
     * @author 木子的昼夜编程
     */
    public class Find02 {
        public static void main(String[] args) {
            MyPerson p01 = new MyPerson();
            p01.gender = '男';
            p01.hashCar = true;
            p01.hasHouse =true;
            p01.salary = 10000;
            p01.natures = Arrays.asList(MyPerson.N1,MyPerson.N3,MyPerson.N5,MyPerson.N7,MyPerson.N8);
    
            MyPerson p02 = new MyPerson();
            p02.gender = '男';
            p02.hashCar = true;
            p02.hasHouse =false;
            p02.salary = 10000;
            p02.natures = Arrays.asList(MyPerson.N1,MyPerson.N3,MyPerson.N5,MyPerson.N7,MyPerson.N8);
    
            MyPerson p03 = new MyPerson();
            p03.gender = '女';
            p03.hashCar = false;
            p03.hasHouse = true;
            p03.salary = 10000;
            p03.natures = Arrays.asList(MyPerson.N2,MyPerson.N4,MyPerson.N5,MyPerson.N7,MyPerson.N8);
    
            MyPerson p04 = new MyPerson();
            p04.gender = '女';
            p04.hashCar = false;
            p04.hasHouse = true;
            p04.salary = 7800;
            p04.natures = Arrays.asList(MyPerson.N3,MyPerson.N4,MyPerson.N5,MyPerson.N7,MyPerson.N8);
    
            // 自己跟自己
            System.out.println("1:"+p01.equals(p01));
            // 男-男
            System.out.println("2:"+p01.equals(p02));
            // 性格 1,3,5,7,8  《-》 2,4,5,7,8
            System.out.println("3:"+p01.equals(p03));
            // 可以匹配
            System.out.println("4:"+p01.equals(p04));
            // 没房
            System.out.println("5:"+p02.equals(p03));
            // 没房
            System.out.println("6:"+p02.equals(p04));
        }
    
    }
    
    class MyPerson{
        // 定义几种性格
        public static final String N1 = "孝顺";
        public static final String N2 = "喜欢读书";
        public static final String N3 = "喜欢运动";
        public static final String N4 = "喜欢历史";
        public static final String N5 = "喜欢哲学";
        public static final String N6 = "认为公共场所抽烟是不文明行为";
        public static final String N7 = "认为随地吐痰是不文明行为";
        public static final String N8 = "认为地铁视频外放是不文明行为";
        // 男女
        char gender;
        // 收入
        double salary;
        // 是否有房
        boolean hasHouse;
        // 是否有车
        boolean hashCar;
        // 性格
        List<String> natures;
    
        @Override
        public boolean equals(Object o) {
            MyPerson p2 = (MyPerson)o;
            // 1. 自己跟自己
            if (this == p2) {
                return true;
            }
            // 2. 性别校验
            if (this.gender == p2.gender) {
                return false;
            }
            // 3.计算薪资差值
            double salary01 = this.salary;
            double salary02 = p2.salary;
            // 3.1 计算差值
            double diff = Math.abs(salary02 - salary01);
            // 3.2 获取薪资小的值
            double small = Math.min(salary01, salary02);
            // 3.3 计算差值比例  不能超过0.3
            double v = diff / small;
            if (v > 0.3) {
                return false;
            }
            // 4. 看男生是否有房、有车
            MyPerson boy = this.gender == '男' ? this : p2;
            if(!boy.hasHouse || !boy.hashCar) {
                return false;
            }
            // 5. 性格匹配 必须超过80%
            if (this.natures == null || this.natures.size() == 0
                    || p2.natures == null || p2.natures.size() ==0 ) {
                return false;
            }
            // 5.1 求交集 为了不影响之前对象属性 所以复制一份新的进行比较
            List<String> list01 = new ArrayList<>(this.natures);
            List<String> list02 = new ArrayList<>(p2.natures);
            list01.retainAll(list02);
            // 5.2 计算比例 按照一般惯例我们需要使用Bigdecimal 这里就直接使用double了,不需要那么精确。
            int count = list01.size();
            double bl01 = Double.valueOf(count) / Double.valueOf(this.natures.size());
            double bl02 = Double.valueOf(count) / Double.valueOf(p2.natures.size());
            if (bl01 < 0.8 || bl02 < 0.8) {
                return false;
            }
            return true;
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(gender, salary, hasHouse, hashCar, natures);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130

    输出:

    在这里插入图片描述

    李: 哈哈 写代码真有意思。这不禁让我想起了一个面试题。

    十三:肯定是“==”和“equals”的区别 ?

    李:什么都逃不过我十三哥的钛合金眼呀。

    十三:我怎么感觉你在骂人,但是我证据不足。你给说说这个面试题,我就不跟你计较了。

    李:好的, 一般面试官问刚毕业的,考察一下他们基础知识学得怎么样,就会问“==”和“equals”的区别

    一、“==”:
    1. 基础类型比较:基础类型比较的时候是拿他们的字面值进行比较的,相等就是true,不相等就位false
      (基础类型:byte、short、int、long、float、double、char、boolean)

      比如我们说,年龄比较、身高比较、薪资比较等,一些基础数值的比较都可以用“==”来比较

    2. 引用类型比较:引用类型比较的是对象地址,我们都知道一个引用变量指向的是内存中的一个地址,如果地址相同就返回true,不相同就返回false.
      比如:一般我们很少用“”来比较对象,除非我们有时候会排除自己,会用到 “”,更多地我们是用equals

    3. 引用类型比较遇到过一次坑

      下边输出是什么:

      Integer i01 = 1;
      Integer i02 = 1;
      Integer i03 = 127;
      Integer i04 = 127;
      Integer i05 = 128;
      Integer i06 = 128;
      System.out.println(i01 == i02);
      System.out.println(i03 == i04);
      System.out.println(i05 == i06);
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      结果是:

    在这里插入图片描述

    强调一遍,包装类型,不要用“==”比较值是否相等,这里为什么前两个比较是true

    这个是因为Integer的缓存机制

    在这里插入图片描述

    二、equals
    2.1

    equals最本质功能就是用的“==”

    我们没有定义equals为什么可以直接使用这个方法

    继承了他爹(Object)的衣钵
    在这里插入图片描述

    package test;
    
    /**
     * @author 木子的昼夜编程
     */
    public class Eq02 {
        public static void main(String[] args) {
            T t01 = new T();
            T t02 = new T();
            System.out.println(t01.equals(t02));
        }
        static class T{
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    2.2

    当然了,默认使用的是他爹的方法,但是大部分时候,我们都是有个性的,我们会自定义equals,比如:

    我们看一下常用的String 的 equals方法,可以看到,先用“==”比较是否是同一个对象,然后再逐个比较字符是否都相等,但凡有一个不相等就返回false
    在这里插入图片描述

    package test;
    
    /**
     * @author 木子的昼夜编程
     */
    public class Eq02 {
        public static void main(String[] args) {
            String s1 = new String("01");
            String s2 = new String("02");
            System.out.println(s1.equals(s2));
        }
        static class T{
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    2.3

    至于经常说的,自定义equals,就是普通的方法覆盖,我们最上边已经写过了。

    2.4

    有些面试官,很无聊的会问,hashCode相等的字符串,是不是equals一定相等。

    这时候你就回他三个字:有哈希碰撞的啦。

    是的,不同字符串的哈希值是可能会相等的

    在这里插入图片描述

    那就有人问了,既然Hash会冲突,那我们要HashCode干什么,那我就要问你了,既然你赚钱少,你为啥还要赚钱呢?

    Hash是会冲突,但是概率很小,而且我们可以确定的是如果两个值相等,那么它们的hash值一定相等。

    我们可以先通过HashCode进行分类,然后再从分类里边进行业务操作。分析过HashMap的put操作源码的人应该深有体会。

    之前看到过有人写了这样一段话:

    java集合中有两类,一类是List,一类是Set。前者有序可重复,后者无序不重复。当我们在set中插入元素的时候,可以通过equals来判断元素是否存在,但是如果元素过多,这个方法会比较慢。

    于是有人发明了哈希算法来提高集合查找元素的效率(讲实话,我不知道是不是为了这个发明的哈希算法,但是这个哈希算法确实为类似的功能提升了不少性能)。这种方式将集合分成若干个存储区域,对每个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的哈希吗就可以确定该对象存储在哪个区域。

    hashCode方法可以这样理解:它返回的就是根据对象内存地址换算出来的一个值,这样一来,当集合需要添加新元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置,如果这个位置没有元素,我们就直接放上去,如果有元素了,我们再用equals进行比较,这样就大大降低了equals的使用频次。

    这段话很拗口,但是你可以读三遍,不理解没关系。等你有一天明白他的用处的时候,你就会恍然大悟。

    还记得小时候计算4+5的时候,摆着手指,怎么也算不对,但是现在4+5 是不是很简单,如果没有小时候的不懂,就没有现在的懂。

    所以不懂不可怕,可怕的是你不懂还不学。

  • 相关阅读:
    单链表的定义(数据结构与算法)
    JavaSE_day39(接上File:获取,修改,数组形式获取,获取目录下的java文件,删除目录。回顾以及深入完整介绍IO,使用字符、字节复制文本文件)
    云打印api接口收费吗?
    stm32f4xx-IWDG独立看门狗
    解决uni-app vue3 nvue中使用pinia页面空白问题
    动态导出word
    移动端web开发最佳实践
    利用FastAPI和OpenAI-Whisper打造高效的语音转录服务
    leetcode: 410. 分割数组的最大值
    Pytorch使用torch.utils.data.random_split拆分数据集,拆分后的数据集状况
  • 原文地址:https://blog.csdn.net/qq_36291682/article/details/127593032