java类库的阅读笔记_jdk1.7.0_40_java.util.Collections

来源:互联网 发布:太阳花 知乎 编辑:程序博客网 时间:2024/06/07 00:11

2013 1021:

类:

java.util.Collections

方法:

public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll)

笔记:

这个泛型约束,加了一个extends Object,原因是兼容以前的方法。

在泛型引入之前,这个方法声明是:public static Object min(Collection coll) 。也就是说,以前返回的类型是Object。所以为了兼容性,引入泛型以后,这个方法也要返回Object类型。如果写成<T extends Comparable<? super T>> ,那么返回类型就是Comparable,不符合兼容性。

泛型规则:实际类型是声明的第一个边界类型,如果没有声明,那么就是Object。比如 T extends A & B & C,那么实际类型是A。

也就是说,泛型擦除这个东西,其实可以理解成,在class文件这个级别,只有实际类型,上面的声明相当于:public static Object min(Collection coll)。而其他的约束,都是在编译环节检查的,利用反射,就可以完全绕过这些检查。比如 test(List<? extends Object & String> list),完全可以反射,然后放入一个int值进去。

类:

java.util.Collections

方法:

private static <T> void rotate1(List<T> list, int distance)

笔记:

这个方法的实现很有意思。方法作用是把list所有元素顺移distance个距离。假设一次for循环里,起始位置为p,distance为d,list长度为n。

那么它的实现原理可以用下面两点推导出来:

1、一次for循环内,不会重复设置某个点。因为如果有重复设置某个点,那么往回退得话,肯定会重复起始点p,这个终止条件矛盾。

2、一次for循环内,会在圈上设置一个周期小于n的点阵。证明:假设距离p点最近的点为p+x,那么下一个点必然是p+2x(或者取%n,以下都省略%n说明),因为以p为起点和以p+x为起点,所有条件都是一样的。

想明白原理以后,评估下方法的效率,果然是既省时间,又省空间。

类:

java.util.Collections

方法:

private static void rotate2(List<?> list, int distance) 

笔记:

长链表上面的移位,rotate1已经不适用了,因为get和set操作取元素的耗时很高。这个方法的原理很简单,就是两部分逆序,然后整体逆序。但是想到这个办法就真不简单了。同样是时空便宜。

类:

java.util.Collections

方法:

public static int indexOfSubList(List<?> source, List<?> target)

笔记:

这个方法里面,用了continue tagName;这样的语法来跳到外层继续循环。

tagName:

for (int i = 0; i < 10; i++) {

for (int j = 0; j < 10; j++) {

if (j > 4) {

continue tagName;

}

}

}

换成break的话,也会跳出两层循环,但是不会继续外层循环。

类:

java.util.Collections

笔记:

这个类的Unmodifiable前缀方法名,比如UnmodifiableCollection,实现其实很简单,就是新构造一个类,实现Collection接口,然后返回出去,新类里面对传入的Collection的方法进行包装,任何包含修改动作的方法,都直接抛出异常,这样就达到了Unmodifiable的效果。

同样的,Synchronized前缀方法名,是内建一个同类型对象返回出去,这个新的对象,对各种方法进行封装,任何真正调用原始数据的方法,都被synchronized关键字锁住了。因为这种非常简单的实现,同步是效率比较低的,并且iterator方法无法进行保护。

同样类型的方法系列,还有Checked前缀方法名,Empty前缀方法名,Singleton前缀方法名。

2013 1019:

类:
java.util.Collections
方法:
public static <T extends Comparable<? super T>> void sort(List<T> list)
笔记:
类型变量<T extends Comparable<? super T>>的意思是,传入的类型T,需要实现Comparable接口,并且接口中的变量类型,需要是T或者T的父类。
比如这种类型是满足T的类型约束的:
class A implements Comparable<Object> {
public int compareTo(Object obj) {
}
}
sort方法可以作用在A的List上:Collections.sort(new LinkedList<A>());

sort方法定义成这样的好处是,T对象可以进行比较,并且T对象可以比较的对象,范围很宽,只要是T的父类就可以了。

类:

java.util.Collections

方法:

private static <T> int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key)

笔记:

链表的二进制查找方法,这里面比较特别的是,如何把每次迭代中,位于中间的对象取出来。它调用了取对象的方法

private static <T> T get(ListIterator<? extends T> i, int index)

这个方法,用迭代器的索引位置和index对比,不断挪动迭代器的位置到index去,然后返回对象。

在iteratorBinarySearch方法中,迭代器i不是每次新生成的,而是每次二分查找的迭代中,用的都是同一个迭代器。所以迭代器的轨迹是每次二分中点的挪动轨迹。也就是说,迭代器最多挪动list的长度次。

对比最傻瓜式的取对象方法:list.get(mid) ,效率得到了保障。

类:

java.util.Collections

方法:

public static void reverse(List<?> list)

笔记:

ListIterator对于List来说非常实用,不要总是用Iterator这种通用的迭代器。