母鸡孵出小鸭子
说说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是一样的,小鸭子就可以由母鸡来孵出了.
说说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是一样的,小鸭子就可以由母鸡来孵出了.