1700444220
1700444221
String str1=new String(str);
1700444222
1700444223
String str2=str.substring(0)+“C”;
1700444224
1700444225
System.out.println(“str==str1?”+str1.equals(str1));
1700444226
1700444227
System.out.println(“str==str2?”+str.equals(str2));
1700444228
1700444229
}
1700444230
1700444231
很明显,str与str1是相等的(虽然不是同一个对象,但用equals方法判断是相等的),但它们与str2不相等,这毋庸置疑,因为str2在对象池中重新生成了一个新的对象,其表面值是ABC,那当然与str和str1不相等了。
1700444232
1700444233
说完了subString的小插曲,现在回到List是否相等的判断上来。subList与subString的输出结果是一样的吗?让事实说话,运行结果如下:
1700444234
1700444235
c==c1?false
1700444236
1700444237
c==c2?true
1700444238
1700444239
很遗憾,与String类刚好相反,同样是一个sub类型的操作,为什么会相反呢?仅仅回答“为什么”似不足以平复我们的惊讶,下面就从最底层的源代码来进行分析。
1700444240
1700444241
c2是通过subList方法从c列表中生成的一个子列表,然后c2又增加了一个元素,可为什么增加了一个元素还会相等呢?我们来看subList源码:
1700444242
1700444243
public List<E>subList(int fromIndex, int toIndex){
1700444244
1700444245
return(this instanceof RandomAccess?
1700444246
1700444247
new RandomAccessSubList<E>(this, fromIndex, toIndex):
1700444248
1700444249
new SubList<E>(this, fromIndex, toIndex));
1700444250
1700444251
}
1700444252
1700444253
subList方法是由AbstractList实现的,它会根据是不是可以随机存取来提供不同的SubList实现方式,不过,随机存储的使用频率比较高,而且RandomAccessSubList也是SubList子类,所以所有的操作都是由SubList类实现的(除了自身的SubList方法外),那么,我们就直接来看SubList类的代码:
1700444254
1700444255
class SubList<E>extends AbstractList<E>{
1700444256
1700444257
//原始列表
1700444258
1700444259
private AbstractList<E>l;
1700444260
1700444261
//偏移量
1700444262
1700444263
private int offset;
1700444264
1700444265
//构造函数,注意list参数就是我们的原始列表
1700444266
1700444267
SubList(AbstractList<E>list, int fromIndex, int toIndex){
1700444268
1700444269
/*下标校验,省略*/
[
上一页 ]
[ :1.70044422e+09 ]
[
下一页 ]