泛型集合接口有一个很大的优点,即算法只需要实现一次。
例如,你先要编写一个计算集合中最大元素的算法,你可能每一个集合类都需要实现一遍:

  1. static <T extends Comparable> T max(T[] a);
  2. static <T extends Comparable> T max(ArrayList<T> a);
  3. static <T extends Comparable> T max(LinkedList<T> a);

因为集合方法都集合了迭代器,所以直接使用迭代器来计算最大元素,这样就可以将 max() 实现为能够接受任何实现了 Collection 接口的对象:

  1. // Collections
  2. public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
  3. Iterator<? extends T> i = coll.iterator();
  4. T candidate = i.next();
  5. while (i.hasNext()) {
  6. T next = i.next();
  7. if (next.compareTo(candidate) > 0)
  8. candidate = next;
  9. }
  10. return candidate;
  11. }

排序与混排

Collections 类中的 sort() 可以对实现了 List 接口的集合进行排序。

  1. List<Employee> staff = new LinkedList<>();
  2. ...fill some collection
  3. // 直接排序,需要注意的是,staff 需要实现 Comparable 接口
  4. Collections.sort(staff);
  5. // 可以传入 Comparator 来达到指定排序方式
  6. Collections.sort(staff, Comparator,comparingDouble(Employee.getSalary));
  7. // 上面传入 Comparator 与下面直接调用 List 的 sort() 一样
  8. staff.sort(Comparator.comparingDouble(Employee::getSalary));
  9. // 降序排序:
  10. staff.sort(Comparator.reverseOrder());
  11. // 也可以指定传入的 Compartor 指定降序
  12. staff.sort(Comparator.comparingDouble(Employee::getSalary).reversed());

Collections 类中有 shuffle 算法,已到达随机排序的效果:

  1. Collections.shuffle(staff);

二分查找

Collections 类中的 binarySearch() 实现了二分查找,需要注意的是,集合必须是排好序的。

  1. int i = Collections.binarySearch(List<T extends Comparable<? super T>>, T);
  2. int i = Collections.binarySearch(List<T extends T>, T, Comparator<? super T>);

需要注意的是,binarySearch() 的返回值是插入到 List 中的位置,以保证 List 的有序性。所以,当返回的是负数时,-i - 1 就是保证元素有序性的插入位置。

批操作

  1. coll1.removeAll(coll2); // 从 coll1 中删除 coll2 中出现的所有元素
  2. coll1.retainAll(coll2); // 从 coll1 中删除所有未在 coll2 中出现的所有元素

集合与数组的转换

数组转集合,直接使用 Arrays.asList

  1. String[] values = ...;
  2. HashSet<String> staff = new HashSet<>(Arrays.asList(values));

集合转数组,使用 toArray()

  1. Object[] values = staff.toArray(); // 只能转成 Object
  2. String[] values = (string[]) staff.toArray(); // ClassCastException , 不能改变 Object[] 的类型
  3. // 必须使用 toArray() 的变体形式
  4. String[] values = staff.toArray(new String[0]); // 提供一个所需类型长度为 0 的数组
  5. String[] values = staff.toArray(new String[staff.size()]); // 也可以指定大小,效果一样

为什么不能将 String.class 传递到 toArray() 中,是因为,toArray() 不仅要填充一个已有数组,还要创建一个新数组。

编写直接的算法

编写算法尽量接受一个更通用的集合。即接受 Collection 而不是 ArrayListLinkedList