`

母鸡孵出小鸭子 --说说List的contains(Object o)方法.

阅读更多
母鸡孵出小鸭子
说说List的contains(Object o)方法.

在编码时遇到这样一个问题:
    Excel文件中有如下记录:
        Title        Name    Note
        Manager        Lincon    afjdksal
        Coder        Clinton    arueiwqo
        Designer    Wend    zmvcx
        ......                ..........    ..........
        ......                ..........    ..........

    对应的文件结构是这样的:
    --parentfolder:
        --folder1:
            manager&Lincon.mid
            coder&clinton.mid
            designer&wend.mid
            .......................
        --folder2:
            manager&Lincon.mp3
            coder&clinton.mp3
            designer&wend.mp3
            .......................
        --folder3:
            manager&Lincon.rm
            coder&clinton.rm
            designer&wend.rm
            .......................

要求通过对excel文件的解析,判断出一条记录在三个子文件中有否有对应的audio文件存在.

先写了两个类来描述这两种现象:ExcelRecord和FileName

这怎么来判断呢?......后来边想边写,总不能自己用多层循环来查找吧.......后来突然想到用List这个接口里的contains()方法了,但以住用这个contains()方法里,所判断可都是同一个类有对象呀.于是想到让这两个类都继承自同一个父类NameInfo.这样在定义List对象时用List<NameInfo>,调用contains时就达到以前所常见的那种情景了.
 
   (期间想过让这个两个类ExcelRecord和FileName实现一个接口,如INameInfo,在定义List时这样写List<INameInfo>,似乎也可以达到那种效果.可后来一想,这里用contains是最终想利用覆盖Object类的那个equals来判断,可INameInfo接口又不能覆盖Object的equals方法,就没有往下多想就否掉了这个想法.不过,这样的一个念头让我想起了Serializable这样标签接口的应用.)

有了以上的想法就开始往下写了,在定义List<NameInfo> records时,想着让它里面放进去ExcelRecord类的对象,这样只要覆盖了ExcelRecord类的equals()方法可以达到判的效果了.

写完后没有用JUnit手动地写一个main来测试,发现不行!这是怎么回事?用Debug来跟踪代码的执行情况,有了惊天大发现:
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

    public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
        } else {
            for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
        }
        return -1;    
    }

原来contains在调用eqauls方法时是这样调用的:o.equals(elementData[i])的,而不是以前所想像的那样elementData[i].equals(o)!

这样就根本没有必要让这个两个类(ExcelRecord,FileName)继承同一个父类NameInfo了.再进一步想,也就是说只要FileName类很好地覆盖了Object类的equals方法,ExcelRecord的List里就认可了FileName的存在.

(转而一想,当初Sun的设计师在设计这个contains方法的实现时是很随意在设计成现在的o.equals(elementData[i])这样呢,还是以前已有前车之鉴了呢?越来越感受到高手的伟大了.)

也就是说只要DuckEgg这个类很好地覆盖Object的equals方法,hen(hen为List<HenEgg>的实例)在调用contains时就会认为DuckEgg与HenEgg是一样的,小鸭子就可以由母鸡来孵出了.




    
4
2
分享到:
评论
1 楼 steven_cheng 2008-03-26  
我倒....
equals方法必须满足对称性,也即是说:
o.equals(elementData[i])等价于elementData[i].equals(o)
你是可以让母鸡孵出小鸭子,但是有可能造成鸡飞蛋打:),因为这样做违反了java语言关于equals方法的约束

相关推荐

Global site tag (gtag.js) - Google Analytics