美文网首页程序员
这绝对是我见过最坑的一道笔试题,没有之一

这绝对是我见过最坑的一道笔试题,没有之一

作者: 程序员麦冬 | 来源:发表于2020-07-28 14:21 被阅读0次

这是我见过的最容易出错的一道Java笔试题,如果不是对Set有非常深入的理解,百分百会出错。

下面就来看一下,这道题到底坑在哪里。

题目如下:

定义了一个Person类,重写了hashCode和equals方法,如下图所示:

public class Person {    public int id;    public String name;    public Person(int id, String name) {        this.id = id;        this.name = name;    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        Person person = (Person) o;        if (id != person.id) return false;        return name != null ? name.equals(person.name) : person.name == null;    }    @Override    public int hashCode() {        int result = id;        result = 31 * result + (name != null ? name.hashCode() : 0);        return result;    }    @Override    public String toString() {        return "Person{" +                "id=" + id +                ", name='" + name + '\'' +                '}';    }}

请写出下面一段代码的运行结果

public class Test {    public static void main(String[] args) {        HashSet set = new HashSet();        Person p1 = new Person(1001,"AA");        Person p2 = new Person(1002,"BB");        set.add(p1);        set.add(p2);        p1.name = "CC";        set.remove(p1);        System.out.println(set);    }}

此时的运行结果是怎样的呢?可以先自己猜一下,然后在看运行结果。

此时的输出结果如下所示:

这绝对是我见过最坑的一道笔试题,没有之一

为什么是这样的运行结果呢?

因为存储p1时,是按照p1的哈希值计算的索引位置,之后p1.name进行了修改,那么当删除p1时,会按照现在的p1,也就是name修改后的p1的哈希值计算的索引,此时计算出的索引位置与之前存储p1的索引位置不相同,所以不会把p1删除掉。

那么接着往下看,还有更坑的。

public class Test {    public static void main(String[] args) {        HashSet set = new HashSet();        Person p1 = new Person(1001,"AA");        Person p2 = new Person(1002,"BB");        set.add(p1);        set.add(p2);        p1.name = "CC";        set.remove(p1);        System.out.println(set);        set.add(new Person(1001,"CC"));        Sys,,idtem.out.println(set);    }}

此时的运行结果又是怎样的呢?Person(1001,“CC”)能存储成功吗?可以先自己猜一下,再看运行结果。

此时的运行结果如下所示:

这绝对是我见过最坑的一道笔试题,没有之一

那么为什么是这样的运行结果呢?

因为存储p1时,是按照第一次的哈希值计算的索引位置,也就是按照p1=new Person(1001,“AA”)计算出来的索引位置进行的存储。后来又把name值进行了修改,那么此时p1的id=1001,name=“CC”。当又往Set中添加id=1001,name="CC"的Person时,会按照Person(1001,“CC”)的哈希值计算索引位置,此时计算出的索引位置与之前存储p1时id=1001,name="AA"计算的索引位置不一样,所以可以添加成功。

别急,还有更坑的,接着往下看。

public class Test {    public static void main(String[] args) {        HashSet set = new HashSet();        Person p1 = new Person(1001,"AA");        Person p2 = new Person(1002,"BB");        set.add(p1);        set.add(p2);        p1.name = "CC";        set.remove(p1);        System.out.println(set);        set.add(new Person(1001,"CC"));        System.out.println(set);                set.add(new Person(1001,"AA"));        System.out.println(set);    }}

此时的运行结果又是怎样的呢?当Person(1001,“AA”)再次存储时,到底能不能存储成功呢?

此时的运行结果如下所示:

这绝对是我见过最坑的一道笔试题,没有之一

那么为什么是这样的运行结果呢?

因为当再次存储id=1001,name="AA"的Person时,虽然使用哈希值计算出的索引位置相同,但是因为此时p1的name值为CC,当调用equals方法判断两者是否相等时,会返回false,所以可以存储成功。

注意:Set集合是元素无序、不可重复的集合,如果是把两个相同的元素加入同一个Set 集合中,则添加操作失败。

向HashSet中添加元素的过程:

当向HashSet集合中存入一个元素时,HashSet会先计算出该元素的哈希值,然后把哈希值与数组长度-1进行与运算计算出该元素在HashSet底层数组中的存储位置。然后判断该位置上是否已经存在元素,如果不存在则直接存储成功;如果该位置上已经存在一个或多个元素,那么就会从前往后依次比较元素是否相等。比较时会先比较元素的哈希值,如果哈希值不相同则添加成功。如果哈希值相同则会调用元素所在类的equals方法进行比较;如果equals方法返回true,则表示两者相等,添加失败;如果equals方法返回false,则表示两者不相等,会添加成功。

感谢你看到这里,我是程序员麦冬,一个java开发从业者,深耕行业六年了,每天都会分享java相关技术文章或行业资讯

欢迎大家关注和转发文章,后期还有福利赠送!

相关文章

  • 这绝对是我见过最坑的一道笔试题,没有之一

    这是我见过的最容易出错的一道Java笔试题,如果不是对Set有非常深入的理解,百分百会出错。 下面就来看一下,这道...

  • 最恶心的事情

    深圳一家包子店的老板做的肉包竟然是用老鼠肉,从这之后我再也不敢吃肉包,这绝对是我见过最恶心的事情,没有之一。 我今...

  • 六字心经解决笔试难题

    一.从一道产品经理笔试题说起 我所见过的两类最恶心的题目:一是GRE的作文,二是产品经理的笔试题。说它们恶心不是...

  • 6个字,教你写出高逼格的产品经理笔试答案

    一.从一道产品经理笔试题说起 我所见过的两类最恶心的题目:一是GRE的作文,二是产品经理的笔试题。说它们恶心不是说...

  • 产品经理笔试面试2

    一.从一道产品经理笔试题说起 我所见过的两类最恶心的题目:一是GRE的作文,二是产品经理的笔试题。说它们恶心不是说...

  • 如何用0.01元购买一瓶可乐!

    首先,这绝对不是一道脑筋急转弯的题目,这是一道笔试题,而且这个笔试题出题方还是一个财富500强的企业。 看到此题,...

  • js.Promise 解决地狱回调

    之前见过的一道Promise面试题的答案

  • 一道坑爹的面试题

    网上看到一道坑爹的面试题,代码如下:(js真是处处是坑呀。。。(┬_┬)) 输出结果(chrome下): 作为前端...

  • 面试题之软件测试的流程

    说说公司的软件测试流程,这,是常考的面试题之一。 不同公司的流程不一样,现状决定流程,没有绝对的对错。 以结果为导...

  • 2018-10-21

    做这么多次ppt 你是我见过最坑的模板

网友评论

    本文标题:这绝对是我见过最坑的一道笔试题,没有之一

    本文链接:https://www.haomeiwen.com/subject/kpyfrktx.html