java集合框架完美教程五

算法支持
介绍
Collections 类和 Arrays 类是“集合框架”中的一部分, 它们借助集合类以支持各种新旧算法。接下来,我们描述几个不同的操作,从排序和搜索开始。
回页首
对数组排序
虽然 TreeSet 类和 TreeMap 类提供集和映射的有序形式, 但没有有序的 List 集合实现。而且,“集合框架”出现之前,对数组排序的内建支持还不存在。您把对 List 排序的支持和对包括基本数据类型在内的任何类型数组的排序支持作为框架的一部分。对于任何排序来说,所有项必须是可以互相比较的(互相可比)。如果不是的话,就会抛出 ClassCastException 异常。
List 的排序是通过 Collections 类中两种 sort() 方法之一完成的。如果元素类型能实现 Comparable,那么您就使用 sort(List list) 形式。否则,您就需要提供一个 Comparator 并使用 sort(List list, Comparator comparator)。这两种形式对于 List 都是不好的,它们保证了 O(n log 2 n) 性能(或更好),用归并排序的变种对 LinkedList 排序也是如此。
数组排序可以用十八种不同方法中的一种来完成。七种基本数据类型(除了 boolean 之外)数组中每一种都有两种方法对其排序,一种对整个数组排序,另一种对部分数组排序。剩下的四种都用于对象数组(Object[ ])的排序。
对基本数据类型的数组排序,只要把您的数组作为参数来调用 Arrays.sort() 并由编译器决定选取下列方法中的一个:
void sort(byte array[ ])
void sort(byte array[ ], int fromIndex, int toIndex)
void sort(short array[ ])
void sort(short array[ ], int fromIndex, int toIndex)
void sort(int array[ ])
void sort(int array[ ], int fromIndex, int toIndex)
void sort(long array[ ])
void sort(long array[ ], int fromIndex, int toIndex)
void sort(float array[ ])
void sort(float array[ ], int fromIndex, int toIndex)
void sort(double array[ ])
void sort(double array[ ], int fromIndex, int toIndex)
void sort(char array[ ])
void sort(char array[ ], int fromIndex, int toIndex)
对象数组的排序有一点棘手,因为编译器不会为您检查每样东西。如果数组里的对象实现 Comparable,那么您就直接对数组整个或部分排序就可以了。否则,您就必须提供一个 Comparator 为您排序。如果您不喜欢缺省的排序,您也可以提供一个 Comparator 实现。
void sort(Object array[ ])
void sort(Object array[ ], int fromIndex, int toIndex)
void sort(Object array[ ], Comparator comparator)
void sort(Object array[ ], int fromIndex, int toIndex, Comparator comparator)
回页首
搜索
除了排序之外,Collections 和 Arrays 类提供在 Collection 中查找最大值和最小值的机制,还提供对 List 或数组进行搜索的机制。
虽然您可以使用 List 的 contains() 方法查明某个元素是不是该列表的一部分,但它假定该列表是无序的。如果您预先使用 Collections.sort()对 List 进行了排序, 您就可以使用一种或两种覆盖的 binarySearch() 方法进行更快的二分搜索。如果 List 的对象实现 Comparable,那么就不需要提供 Comparator 了。否则,您必须提供 Comparator。此外,如果您用某个 Comparator 进行排序,您必须在二分搜索时使用同一个 Comparator。
public static int binarySearch(List list, Object key)
public static int binarySearch(List list, Object key, Comparator comparator)
如果要搜索的 List 是 AbstractSequentialList 的子类(就像 LinkedList),那么顺序的搜索实际上已经完成了。
数组搜索与之类似。用完其中一个 Arrays.sort() 方法后,您能得到生成的数组并搜索元素。binarySearch() 有七种用于搜索基本数据类型(除了 boolean)而覆盖的方法变体和两种搜索 Object 数组的方法变体,其中有的使用 Comparator,有的不使用。
如果原始的 List 或数组是无序的,则结果不确定。
除了在 List 内搜索特定元素,您还可以在任意 Collection 中搜索极端元素:最大值和最小值。如果已知集合已经排好序了,只要获取第一个和最后一个元素就行了。但是,对于无序的集合,您可以使用 Collections 的 min() 或 max() 方法。如果集合中的对象不实现 Comparable,那么您必须提供 Comparator。
Object max(Collection collection)
Object max(Collection collection, Comparator comparator)
Object min(Collection collection)
Object min(Collection collection, Comparator comparator)
回页首
检查等同性
虽然 MessageDigest 类总是提供 isEqual() 方法来比较两个 byte 数组,但是,除非数组都来自消息摘要(message digest),否则用这种方法比较 byte 数组永远是错误的。现在,有了 Arrays 类的帮助,您可以检查任何基本数据类型数组或对象数组的等同性。 如果两个数组包含顺序相同的相同元素,则这两个数组相等。 检查对象数组的等同性依赖于每个要检查等同性对象的 equals() 方法。
byte array1[] = ...;
byte array2[] = ...;
if (Arrays.equals(array1, array2) {
  // They're equal
}
回页首
元素的操作
Collections 和 Arrays 类提供了在 List 或数组中操作元素的一些方法。除此之外就再没有操作其它关键框架接口(Set 和 Map)的其它方法了。
Collections 类借助 List 让您用单个元素替代每个元素,如复制整个列表到另一个列表、颠倒所有元素的顺序或者把元素顺序打乱。在从一张列表复制到另一张的时候,如果目的列表比原始列表大,则剩余元素不变。
void fill(List list, Object element)
void copy(List source, List destination)
void reverse(List list)
void shuffle(List list)
void shuffle(List list, Random random)
Arrays 类允许您通过 fill() 方法的十八种覆盖形式以一个元素替代整个或部分数组。所有方法都形如 fill(array, element) 或 fill(array, fromIndex, toIndex, element)。
回页首
大 O(Big-O)符号
大小为 n 的集合的排序和搜索操作性能用大 O(Big-O)符号来衡量。 该符号描述了 n 值很大时算法复杂性和算法操作的最长时间之间的关系。例如,如果您在整个集合中迭代以寻找某个元素,大 O 符号就是指 O(n) 的形式,意思是当 n 增加时,在大小为 n 的集合中查找元素的时间也线性增加。 这说明大 O 符号假定的是最坏情况的性能。让操作更快总是可能的。
下表显示 n 为 65,536 时,不同操作的大 O 值。此外,这个操作计数还展示了如果您要对一个集合执行多次搜索操作,与每次进行线性搜索相比,先对集合进行快速排序,然后再搜索会更快。(而且,我们应该避免冒泡排序,除非 n 真的很小!)
描述 Big-O # 操作 示例
常数 O(1) 1 散列表查找(理想情况)
对数 O(log2n) 16 对有序集合进行二分搜索
线性 O(n) 65,536 线性搜索
线性对数 O(n x log2n) 1,048,576 快速排序
二次方程 O(n x n) 4,294,967,296 冒泡排序
注:n = 65536

你可能感兴趣的:(Java集合框架)