java - 为什么这个代码的结果会是随机的?
高洛峰
高洛峰 2017-04-17 15:58:09
[Java讨论组]
高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回复(3)
PHP中文网

这是一个很好的基础问题,包含了对equals方法的理解,以及ArrayList的remove方法的理解。
为何remove("aa")就能够将add进去的"aa"给移除了,而new进去的Date却不能,还看似有随机性呢。
顺着这样的思考思路,就应该去查看ArrayList的remove方法。

public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }
    

通过源码查看能够看到,ArrayList的remove方法是要通过你所传进去的对象的equals来进行判断的,如果equals方法返回的是True那么就认定这两个对象是“相等”的,所以问题就转化为“Date的equals方法是如何判断两个对象相同的”。接下来查看Date的equals方法源码

public boolean equals(Object obj) {
        return obj instanceof Date && getTime() == ((Date) obj).getTime();
    }
    

看上面的代码十分简单,不用多说了,就是根据getTime()返回的毫秒数来判断的,虽然问题比较简单,但是这样思考问题的方式希望能够分享给提问的朋友。

PHP中文网

public boolean remove(Object o) {

 if (o == null) {
         for (int index = 0; index < size; index++)
     if (elementData[index] == null) {
         fastRemove(index);
         return true;
     }
 } else {
     for (int index = 0; index < size; index++)
     if (o.equals(elementData[index])) {
         fastRemove(index);
         return true;
     }
     }
 return false;
 }

这是ArrayList的源码,首先通过代码可以看到,当移除成功后返回true,否则返回false。remove(Object o)中通过遍历element寻找是否存在传入对象,一旦找到就调用fastRemove移除对象。你两次new date()的不是一个对象。找不到肯定不会remove。你可以在代码中间加上sleep试试

PHP中文网

试了一下,是可能会出现。
看Date的默认构造函数是

 public Date() {
     this(System.currentTimeMillis());
 }

即使用当前的时间作为参数,所以执行时间太短的时候可能会导致两个new Date()实例化两个相等的对象。
Date的equals()方法较复杂,没有仔细分析。不过知道这些,应该差不多了吧。

测试了一下:代码如下:

    list.add("aa");
    list.add(new Date());
    System.out.println(System.currentTimeMillis());
    System.out.println("移除前:"+list.size());
    list.remove("aa");
    list.remove(new Date());
    System.out.println(System.currentTimeMillis());
    
    一次结果为:
    1448642796820
    移除前:2
    1448642796821
    移除后:1
    
    另外一次结果为:
    1448642884334
    移除前:2
    1448642884334
    1448642884334
    1448642884334
    移除后:0

   
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号