Collections 是为了方便使用集合而产生的工具类,Arrays 方便数组使用,Collections 是方便集合使用。
1、排序sort
1.1原理
对已知集合c进行排序,底层还是调用的Arrays的sort方法。这部分在之前的文章已经讲过了,Java集合框架Arrays的常见方法
1.2例子
public static void main(String[] args){
List c = new ArrayList();
c.add("学习");
c.add("Java");
c.add("的");
c.add("小姐姐");
System.out.println(c);
Collections.sort(c);
System.out.println(c);
}
2.反转reverse()
2.1源码分析
反转集合中元素的顺序。
public static void reverse(List<?> list) {
int size = list.size();
if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
swap(list, i, j);
} else {
// instead of using a raw type here, it's possible to capture
// the wildcard but it will require a call to a supplementary
// private method
ListIterator fwd = list.listIterator();
ListIterator rev = list.listIterator(size);
for (int i=0, mid=list.size()>>1; i<mid; i++) {
Object tmp = fwd.next();
fwd.set(rev.previous());
rev.set(tmp);
}
}
}
1. 如果集合大小小于REVERSE_THRESHOLD(18)或者支持随机访问,则直接交换位置,注意原文中调用来swap(llist, i, j)方法,这个方法只有两行,代码写得很精妙:
@SuppressWarnings({"rawtypes", "unchecked"})
public static void swap(List<?> list, int i, int j) {
// instead of using a raw type here, it's possible to capture
// the wildcard but it will require a call to a supplementary
// private method
final List l = list;
l.set(i, l.set(j, l.get(i)));
}
2. 采用两个迭代器,分别从开端和末端遍历,进行元素交换;这里的迭代器支持指针向前移动。
2.2例子
public static void main(String[] args){
List c = new ArrayList();
c.add("学习");
c.add("Java");
c.add("的");
c.add("小姐姐");
System.out.println(c);
Collections.reverse(c);
System.out.println(c);
}
3.最大值max,最小值min
3.1源码解析
我们以 max 方法为例来说明一下,max 提供了两种类型的方法,一个需要传外部排序器,一个不需要传排序器,但需要集合中的元素强制实现 Comparable 接口,后者的泛型定义很有意思,我们来看下(从右往左看)
从这段源码中,我们可以学习到两点:
1. max 方法泛型 T 定义得非常巧妙,意思是泛型必须继承 Object 并且实现 Comparable 的接一般让我们来定义的话,我们可以会在方法里面去判断有无实现 Comparable 的接口,这种是在运行时才能知道结果。而这里泛型直接定义了必须实现 Comparable 接口,在编译的时候就可告诉使用者,当前类没有实现 Comparable 接口,使用起来很友好;
2. 给我们提供了实现两种排序机制的好示例:第一个采用Collection内含自然比较法,第二个采用Comparator进行比较
3.2例子
public static void main(String[] args){
List c = new ArrayList();
c.add("学习");
c.add("Java");
c.add("的");
c.add("小姐姐");
System.out.println(c);
System.out.println(Collections.max(c));
}
4.线程安全的集合
Collections提供了很多线程安全的集合,针对 List、Map、Set 都有提供,我们先来看下线程安全的集合
我们以 synchronizedList 为例来说下底层的实现:可以看到 List 的所有操作方法都被加上了 synchronized 锁,所以多线程对集合同时进行操作,是线程安全的。
5.不可变的集合
得到不可变集合的方法都是以 unmodifiable 开头的。这类方法的意思是,我们会从原集合中,得到一个不可变的新集合,新集合只能访问,无法修改;一旦修改,就会抛出异常。这主要是为只开放了查询方法,其余任何修改操作都会抛出异常,
我们以 unmodifiableList 为例来看下,底层是直接抛出异常的。