2013 1024:
类:
方法:java.util.LinkedList
public Object clone()
笔记:
LinkedList的克隆是浅克隆。新的LinkedList对象,里面包含的元素引用,都是指向的原来LinkedList中的元素。这种实现其实是因为,作为容器,不可能约束元素一定要实现Cloneable。作为一个列表元素顺序的备份,这种浅克隆似乎已经足够使用了。
clone方法都要先调用super.clone,最重要的原因,是要能够调到Object的native clone方法。这个方法据说将实际对象在内存中的状态拷贝了一份出来,从而一层一层的clone方法,才有施展的空间。也只有native方法才能这么牛吧,不然用java代码的执行方式,Object对象的clone方法,是没法知道真正的子类对象,是个什么数据格式的吧。
类:
java.util.LinkedList$ListItr
笔记:
作为非静态内部类,每一个new出来的ListItr对象,都会隐含拥有一个LinkedList对象引用,可以直接使用这个对象的所有属性和方法。这也是为什么,非静态内部类,在客户端声明的时候,需要用 new OutClass().new InnerClass()这种格式。
今天看到一个C++转过来的前辈写的代码,我默默垂泪,简化如下:
class Outer {
void exe(){};
private class Inner Implements Runnable {
Outer xx = null;
public Inner(Outer xx) {
this.xx = xx;
}
public void run() {
xx.exe();
}
}
void dosomething() {
// addTask(new Inner(this), timeset);
}
}
类:
方法:java.util.LinkedList$ListItr
public void remove()
笔记:
之前一直以为,迭代器是使用index,或者指针,指向某个元素,每次next都移到下一个元素,每次remove,都删除当前元素。这种理解完全错了。
remove的注释中,说明了这个方法每次移除的,是使用next方法,或者previous方法,返回出去的对象(也许一般的Iterator没有previous方法,但是remove的意义是一样的)。从ListIterator的几个方法上来看,remove方法确实应该这样定义。我们一般使用的时候,就是把一个元素拿出来,然后取一下数据,或者看一下状态,不合意的就删掉这个元素。使用迭代器,我们不会想着处理着当前对象,又要去删链表中的其他的对象。
这个方法不能在ListIterator的add方法之后,直接调用。因为从意义上讲,add方法调用过以后,会在迭代器的下一个元素之前,插入新的元素,而迭代器的下一个元素,可能是刚刚返回出去的元素(调用了previous方法)。如果这时候remove方法可用,那么再调用remove方法,就相当于删掉了迭代器后面的后面的元素,这不符合迭代器的迭代遍历的设计。
类:
方法:java.util.LinkedList$ListItr
public E previous()
笔记:
这个方法是ListIterator中的方法,它的作用是,返回前一个元素,并且迭代器前移一位。
可以把ListIterator想象成在LinkedList节点中间跳动的点,next方法返回下一个node,并且迭代器跳到下一个中间点,previous方法返回前一个node,并且迭代器跳到前一个中间点。
2013 1022:
类:
java.util.LinkedList
笔记:
这个类里面,绝大部分方法的局部变量,都用了final修饰,因此特意找了一下用final修饰有什么好处。
有如下三种说法:
1、防止自己或者其他人修改变量,以避免失误写错。
2、方法的内部类会将方法的局部final变量拷贝到自己的域中,从而可以用到局部变量
3、便于编译器进行编译的优化。
这里面,2这个说法是正确的,我看了class文件,确实final变量被编译到局部方法的内部类中去了。如果有这种应用场景,那只能如此了。1完全是编码风格问题,有的人喜欢final,有的人讨厌final。比如LinkedList里面到处是final变量,但是在Collections里面,根本没有一个final修饰局部变量。3的话,真没看出来。不管是不是final的,局部变量就是局部变量,占用的还是那个Slot,生命周期也是一样的,哪有什么效率差别。