泛型集合接口有一个很大的优点,即算法只需要实现一次。
例如,你先要编写一个计算集合中最大元素的算法,你可能每一个集合类都需要实现一遍:
static <T extends Comparable> T max(T[] a);static <T extends Comparable> T max(ArrayList<T> a);static <T extends Comparable> T max(LinkedList<T> a);
因为集合方法都集合了迭代器,所以直接使用迭代器来计算最大元素,这样就可以将 max() 实现为能够接受任何实现了 Collection 接口的对象:
// Collectionspublic static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {Iterator<? extends T> i = coll.iterator();T candidate = i.next();while (i.hasNext()) {T next = i.next();if (next.compareTo(candidate) > 0)candidate = next;}return candidate;}
排序与混排
Collections 类中的 sort() 可以对实现了 List 接口的集合进行排序。
List<Employee> staff = new LinkedList<>();...fill some collection// 直接排序,需要注意的是,staff 需要实现 Comparable 接口Collections.sort(staff);// 可以传入 Comparator 来达到指定排序方式Collections.sort(staff, Comparator,comparingDouble(Employee.getSalary));// 上面传入 Comparator 与下面直接调用 List 的 sort() 一样staff.sort(Comparator.comparingDouble(Employee::getSalary));// 降序排序:staff.sort(Comparator.reverseOrder());// 也可以指定传入的 Compartor 指定降序staff.sort(Comparator.comparingDouble(Employee::getSalary).reversed());
Collections 类中有 shuffle 算法,已到达随机排序的效果:
Collections.shuffle(staff);
二分查找
Collections 类中的 binarySearch() 实现了二分查找,需要注意的是,集合必须是排好序的。
int i = Collections.binarySearch(List<T extends Comparable<? super T>>, T);int i = Collections.binarySearch(List<T extends T>, T, Comparator<? super T>);
需要注意的是,binarySearch() 的返回值是插入到 List 中的位置,以保证 List 的有序性。所以,当返回的是负数时,-i - 1 就是保证元素有序性的插入位置。
批操作
coll1.removeAll(coll2); // 从 coll1 中删除 coll2 中出现的所有元素coll1.retainAll(coll2); // 从 coll1 中删除所有未在 coll2 中出现的所有元素
集合与数组的转换
数组转集合,直接使用 Arrays.asList:
String[] values = ...;HashSet<String> staff = new HashSet<>(Arrays.asList(values));
集合转数组,使用 toArray():
Object[] values = staff.toArray(); // 只能转成 ObjectString[] values = (string[]) staff.toArray(); // ClassCastException , 不能改变 Object[] 的类型// 必须使用 toArray() 的变体形式String[] values = staff.toArray(new String[0]); // 提供一个所需类型长度为 0 的数组String[] values = staff.toArray(new String[staff.size()]); // 也可以指定大小,效果一样
为什么不能将
String.class传递到toArray()中,是因为,toArray()不仅要填充一个已有数组,还要创建一个新数组。
编写直接的算法
编写算法尽量接受一个更通用的集合。即接受 Collection 而不是 ArrayList 或 LinkedList
