==和equals

发布于:2022-10-29 ⋅ 阅读:(316) ⋅ 点赞:(0)

好人卡

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

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

李:周末干啥啦

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

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

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

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

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

李:我去领了一张卡片。

十三:办银行卡啦?

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

十三:哦啊,明白了。

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

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

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

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

李:对,十三哥说的是。

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

十三:你说

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

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

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

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

李:且说无妨。

十三:无非是钱、貌

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

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

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

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

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

李:很滑稽。

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

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

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

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

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

以下内容纯属虚构:

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

其次,一男一女,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;
}

输出:

在这里插入图片描述

十三:你这还需要一个专门的方法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);
    }
}

输出:

在这里插入图片描述

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

十三:肯定是“==”和“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);
    

    结果是:

在这里插入图片描述

强调一遍,包装类型,不要用“==”比较值是否相等,这里为什么前两个比较是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{

    }
}

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{

    }
}

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 是不是很简单,如果没有小时候的不懂,就没有现在的懂。

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

本文含有隐藏内容,请 开通VIP 后查看