首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Collections种

2012-09-10 
Collections类Collections类提供了一些列静态方法用于操作集合。注意如果传入Collections类静态方法的集合

Collections类
Collections类提供了一些列静态方法用于操作集合。
注意如果传入Collections类静态方法的集合参数为空时会抛出空指针异常
常用方法:
1.addAll(Collection<? super T> c, T... elements)
  //可以添加单个元素或是T数组到指定c集合中
2.sort(List<T> list)
  //按照T元素默认的比较关系进行排序(内部自定义排序)
  //T是实现Comparable接口的类
3.sort(List<T> list, Comparator<? super T> c)
  //按照自定义排序规则进行排序(外部自定义排序)
注意这里说说Comparable和Comparator的区别
Comparable是当对象元素需要排序时,可以让实现该接口。实现其中
的 public int compareTo(T o)方法
如Integer类就是
public final class Integer extends Number implements Comparable<Integer>
其实现的compareTo方法如下
public int compareTo(Integer anotherInteger) {
   int thisVal = this.value;
   int anotherVal = anotherInteger.value;
   return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}
即小于返回-1,等于返回0,大于返回1
因此就可以直接调用sort(List<Integer> list)类。
如果对于自定义对象,如果该对象没有实现Comparable接口,则可以创建一个类实现Comparator接口,实现其中的比较方法,传入sort(List<T> list, Comparator<? super T> c)方法,或是使用匿名内部类直接在方法中new Comparator,然后定义元素的比较规则

自定义排序方法的源码如下
public static <T> void sort(List<T> list, Comparator<? super T> c) {
Object[] a = list.toArray();//将list转换成对象数组
Arrays.sort(a, (Comparator)c);//然后调用Arrays的排序
ListIterator i = list.listIterator();
for (int j=0; j<a.length; j++) {
    i.next();
    i.set(a[j]);//最后将排好序的数组重新设置到list中
         }
}
4.int binarySearch(List<?extends Comparable<? super T>> list,T key)
//二分法查找集合中的是否包含指定的元素
//要求元素继承自Comparable接口
//要求list是排号顺序的
//返回的是查找到的索引位置,如果没有找到则返回-1
5.binarySearch(List<?extends T> list,T key,Comparator<? super T> c)
//二分法查找指定元素,但是会按照传入的Comparator比较元素的大小
//要求list是排号顺序的
//返回的是查找到的索引位置,如果没有找到则返回-1
6.copy(List<? super T> dest, List<? extends T> src)
//拷贝src集合元素到目标集合中
//内部实现就是将判断src的大小是否大于des的大小,然后对src进行遍历,并将取出的值
//添加到des集合中
7.enumeration(Collection<T> c)
//返回一个指向collection的枚举
8.max(Collection<? extends T> coll)
//返回集合中最大的元素
9.max(Collection<? extends T> coll, Comparator<? super T> comp)
//按照自定义的比较规则返回集合中最大的元素
10.min(Collection<? extends T> coll)
11.min(Collection<? extends T> coll, Comparator<? super T> comp)
12.reverse(List<?> list)
//反置有序的集合
13.synchronizedList(List<T> list)
//返回一个安全的list
14.synchronizedMap(Map<K,V> m)
//返回安全的map
15.synchronizedSet(Set<T> s)
//返回安全的set

//这里看看几个知识点
public static <T> List<T> synchronizedList(List<T> list) {
return (list instanceof RandomAccess ?
                new SynchronizedRandomAccessList<T>(list) :
                new SynchronizedList<T>(list));
}
这个方法是返回安全的list
知识点 : 使用类泛型
          SynchronizedList是一个静态的内部类
          SynchronizedList实现了List的接口
1).第一个<T>表示定义一个泛型变量T。这样后面就能使用泛型变量T
2).SynchronizedList是一个静态内部类,这个内部类主要的作用就是把外部传入的一个非安全的list转换成安全的list。
因为是要转换成安全的list,所以要实现List接口,暴露给外部同list相同接口。
可以看见这个内部类是
public E get(int index) {
    synchronized(mutex) {return list.get(index);}
}
是对list的每个方法都完成了同步。mutex只是用于同步而定义的变量,该对象指向的是该对象本身。
知识点2:数组克隆
public static <T extends Comparable<? super T>> void sort(List<T> list)
{
Object[] a = list.toArray();
Arrays.sort(a);
ListIterator<T> i = list.listIterator();
for (int j=0; j<a.length; j++) {
    i.next();
    i.set((T)a[j]);
         }
}
上面的排序方法,实际上是先将list转换成对象数组,然后对对象数组进行排序。
而Arrays.sort方法实际上是先对数组进行克隆,这样就相当于重新分配了一个堆内存。
然后里面数组元素的排序不会修改原有传入的数组顺序。
public static void sort(Object[] a) {
        Object[] aux = (Object[])a.clone();
        mergeSort(aux, a, 0, a.length, 0);
}
但是注意如果数组元素是自定义对象,那么修改克隆出的数组元素会让原始数组元素发生改变。
因为对于基本数据类型数组分配内存时,保存的是基本数据类型的值,但是对于复杂的对象类型会保存对象的引用地址最为数组元素的值
最后说一点java数组的知识:
如果只写int[] array;则只会在栈内存中分配空间,没有指向堆内存的任何对象。
数组的初始化分为静态初始化和动态初始化
静态初始化就是int [] array = {1,2,3} //array会直接指向堆内存
动态初始化就是 int[] array = new array[3];//array也会指向堆内存,但是堆内存中数组元素的值是0.
动态初始化的情况下:如果元素的类型是double类型,默认值是0.0,如果是boolean类型,默认的初始值是false。

热点排行