简介
- 上一篇我们学习了 Arrays的工具类,同样的,Collections 也是JDK提供的工具类。
因为Collections是JDK官方提供的操作集合的工具类,所以很多部分都是重载方法,本篇只举例说明,因为使用的方法是一致的。本篇暂时不学习其内部过多的内部类
public class Collections {private Collections() {}private static final int BINARYSEARCH_THRESHOLD = 5000;private static final int REVERSE_THRESHOLD = 18;private static final int SHUFFLE_THRESHOLD = 5;private static final int FILL_THRESHOLD = 25;private static final int ROTATE_THRESHOLD = 100;private static final int COPY_THRESHOLD = 10;private static final int REPLACEALL_THRESHOLD = 11;private static final int INDEXOFSUBLIST_THRESHOLD = 35;// 排序public static <T extends Comparable<? super T>> void sort(List<T> list) {list.sort(null);}// 二分查找public static <T>int binarySearch(List<? extends Comparable<? super T>> list, T key) {if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)return Collections.indexedBinarySearch(list, key);elsereturn Collections.iteratorBinarySearch(list, key);}// 二分查找辅助类private static <T>int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {int low = 0;int high = list.size()-1;while (low <= high) {int mid = (low + high) >>> 1;Comparable<? super T> midVal = list.get(mid);int cmp = midVal.compareTo(key);if (cmp < 0)low = mid + 1;else if (cmp > 0)high = mid - 1;elsereturn mid; // key found}return -(low + 1); // key not found}private static <T>int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key){int low = 0;int high = list.size()-1;ListIterator<? extends Comparable<? super T>> i = list.listIterator();while (low <= high) {int mid = (low + high) >>> 1;Comparable<? super T> midVal = get(i, mid);int cmp = midVal.compareTo(key);if (cmp < 0)low = mid + 1;else if (cmp > 0)high = mid - 1;elsereturn mid; // key found}return -(low + 1); // key not found}// 获取第i个元素private static <T> T get(ListIterator<? extends T> i, int index) {T obj = null;int pos = i.nextIndex();if (pos <= index) {do {obj = i.next();} while (pos++ < index);} else {do {obj = i.previous();} while (--pos > index);}return obj;}// 反转指定列表中元素的顺序。// 此方法以线性时间运行。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 methodListIterator 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);}}}// 随机的置换使用随机的默认源指定列表 随机置换列表public static void shuffle(List<?> list) {Random rnd = r;if (rnd == null)r = rnd = new Random(); // harmless race.shuffle(list, rnd);}// 随机对象private static Random r;// 元素互换操作public static void swap(List<?> list, int i, int j) {final List l = list;l.set(i, l.set(j, l.get(i)));}private static void swap(Object[] arr, int i, int j) {Object tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}// 替换所有指定列表与指定元素的元素。public static <T> void fill(List<? super T> list, T obj) {int size = list.size();if (size < FILL_THRESHOLD || list instanceof RandomAccess) {for (int i=0; i<size; i++)list.set(i, obj);} else {ListIterator<? super T> itr = list.listIterator();for (int i=0; i<size; i++) {itr.next();itr.set(obj);}}}// 将所有从一个列表中的元素到另一个的public static <T> void copy(List<? super T> dest, List<? extends T> src) {int srcSize = src.size();if (srcSize > dest.size())throw new IndexOutOfBoundsException("Source does not fit in dest");if (srcSize < COPY_THRESHOLD ||(src instanceof RandomAccess && dest instanceof RandomAccess)) {for (int i=0; i<srcSize; i++)dest.set(i, src.get(i));} else {ListIterator<? super T> di=dest.listIterator();ListIterator<? extends T> si=src.listIterator();for (int i=0; i<srcSize; i++) {di.next();di.set(si.next());}}}// 返回集合中的最小元素public static <T extends Object & Comparable<? super T>> T min(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;}// 返回集合自然排序最大的元素public 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;}// 旋转在指定列表中的元素由所述指定的距离public static void rotate(List<?> list, int distance) {if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD)rotate1(list, distance);elserotate2(list, distance);}private static <T> void rotate1(List<T> list, int distance) {int size = list.size();if (size == 0)return;distance = distance % size;if (distance < 0)distance += size;if (distance == 0)return;for (int cycleStart = 0, nMoved = 0; nMoved != size; cycleStart++) {T displaced = list.get(cycleStart);int i = cycleStart;do {i += distance;if (i >= size)i -= size;displaced = list.set(i, displaced);nMoved ++;} while (i != cycleStart);}}private static void rotate2(List<?> list, int distance) {int size = list.size();if (size == 0)return;int mid = -distance % size;if (mid < 0)mid += size;if (mid == 0)return;reverse(list.subList(0, mid));reverse(list.subList(mid, size));reverse(list);}// 替换public static <T> boolean replaceAll(List<T> list, T oldVal, T newVal) {boolean result = false;int size = list.size();if (size < REPLACEALL_THRESHOLD || list instanceof RandomAccess) {if (oldVal==null) {for (int i=0; i<size; i++) {if (list.get(i)==null) {list.set(i, newVal);result = true;}}} else {for (int i=0; i<size; i++) {if (oldVal.equals(list.get(i))) {list.set(i, newVal);result = true;}}}} else {ListIterator<T> itr=list.listIterator();if (oldVal==null) {for (int i=0; i<size; i++) {if (itr.next()==null) {itr.set(newVal);result = true;}}} else {for (int i=0; i<size; i++) {if (oldVal.equals(itr.next())) {itr.set(newVal);result = true;}}}}return result;}// 返回指定目标列表中第一次出现的指定源列表中的起始位置,或-1public static int indexOfSubList(List<?> source, List<?> target) {int sourceSize = source.size();int targetSize = target.size();int maxCandidate = sourceSize - targetSize;if (sourceSize < INDEXOFSUBLIST_THRESHOLD ||(source instanceof RandomAccess&&target instanceof RandomAccess)) {nextCand:for (int candidate = 0; candidate <= maxCandidate; candidate++) {for (int i=0, j=candidate; i<targetSize; i++, j++)if (!eq(target.get(i), source.get(j)))continue nextCand; // Element mismatch, try next candreturn candidate; // All elements of candidate matched target}} else { // Iterator version of above algorithmListIterator<?> si = source.listIterator();nextCand:for (int candidate = 0; candidate <= maxCandidate; candidate++) {ListIterator<?> ti = target.listIterator();for (int i=0; i<targetSize; i++) {if (!eq(ti.next(), si.next())) {// Back up source iterator to next candidatefor (int j=0; j<i; j++)si.previous();continue nextCand;}}return candidate;}}return -1; // No candidate matched the target}// 返回指定目标列表中最后一次出现的指定源列表中的起始位置,或-1public static int lastIndexOfSubList(List<?> source, List<?> target) {int sourceSize = source.size();int targetSize = target.size();int maxCandidate = sourceSize - targetSize;if (sourceSize < INDEXOFSUBLIST_THRESHOLD ||source instanceof RandomAccess) { // Index access versionnextCand:for (int candidate = maxCandidate; candidate >= 0; candidate--) {for (int i=0, j=candidate; i<targetSize; i++, j++)if (!eq(target.get(i), source.get(j)))continue nextCand; // Element mismatch, try next candreturn candidate; // All elements of candidate matched target}} else { // Iterator version of above algorithmif (maxCandidate < 0)return -1;ListIterator<?> si = source.listIterator(maxCandidate);nextCand:for (int candidate = maxCandidate; candidate >= 0; candidate--) {ListIterator<?> ti = target.listIterator();for (int i=0; i<targetSize; i++) {if (!eq(ti.next(), si.next())) {if (candidate != 0) {// Back up source iterator to next candidatefor (int j=0; j<=i+1; j++)si.previous();}continue nextCand;}}return candidate;}}return -1; // No candidate matched the target}// 内部类 SynchronizedCollection 实现了Collection接口 内部的方法使用 关键字 synchronized修饰,是线程安全的static class SynchronizedCollection<E> implements Collection<E>, Serializable {private static final long serialVersionUID = 3053995032091335093L;final Collection<E> c; // Backing Collectionfinal Object mutex; // Object on which to synchronizeSynchronizedCollection(Collection<E> c) {this.c = Objects.requireNonNull(c);mutex = this;}SynchronizedCollection(Collection<E> c, Object mutex) {this.c = Objects.requireNonNull(c);this.mutex = Objects.requireNonNull(mutex);}public int size() {synchronized (mutex) {return c.size();}}public boolean isEmpty() {synchronized (mutex) {return c.isEmpty();}}public boolean contains(Object o) {synchronized (mutex) {return c.contains(o);}}public Object[] toArray() {synchronized (mutex) {return c.toArray();}}public <T> T[] toArray(T[] a) {synchronized (mutex) {return c.toArray(a);}}public Iterator<E> iterator() {return c.iterator(); // Must be manually synched by user!}public boolean add(E e) {synchronized (mutex) {return c.add(e);}}public boolean remove(Object o) {synchronized (mutex) {return c.remove(o);}}public boolean containsAll(Collection<?> coll) {synchronized (mutex) {return c.containsAll(coll);}}public boolean addAll(Collection<? extends E> coll) {synchronized (mutex) {return c.addAll(coll);}}public boolean removeAll(Collection<?> coll) {synchronized (mutex) {return c.removeAll(coll);}}public boolean retainAll(Collection<?> coll) {synchronized (mutex) {return c.retainAll(coll);}}public void clear() {synchronized (mutex) {c.clear();}}public String toString() {synchronized (mutex) {return c.toString();}}// Override default methods in Collection@Overridepublic void forEach(Consumer<? super E> consumer) {synchronized (mutex) {c.forEach(consumer);}}@Overridepublic boolean removeIf(Predicate<? super E> filter) {synchronized (mutex) {return c.removeIf(filter);}}@Overridepublic Spliterator<E> spliterator() {return c.spliterator(); // Must be manually synched by user!}@Overridepublic Stream<E> stream() {return c.stream(); // Must be manually synched by user!}@Overridepublic Stream<E> parallelStream() {return c.parallelStream(); // Must be manually synched by user!}private void writeObject(ObjectOutputStream s) throws IOException {synchronized (mutex) {s.defaultWriteObject();}}}// 再来看一个// SynchronizedSet 也是线程安全的static class SynchronizedSortedSet<E>extends SynchronizedSet<E>implements SortedSet<E>{private static final long serialVersionUID = 8695801310862127406L;private final SortedSet<E> ss;SynchronizedSortedSet(SortedSet<E> s) {super(s);ss = s;}SynchronizedSortedSet(SortedSet<E> s, Object mutex) {super(s, mutex);ss = s;}public Comparator<? super E> comparator() {synchronized (mutex) {return ss.comparator();}}public SortedSet<E> subSet(E fromElement, E toElement) {synchronized (mutex) {return new SynchronizedSortedSet<>(ss.subSet(fromElement, toElement), mutex);}}public SortedSet<E> headSet(E toElement) {synchronized (mutex) {return new SynchronizedSortedSet<>(ss.headSet(toElement), mutex);}}public SortedSet<E> tailSet(E fromElement) {synchronized (mutex) {return new SynchronizedSortedSet<>(ss.tailSet(fromElement),mutex);}}public E first() {synchronized (mutex) {return ss.first();}}public E last() {synchronized (mutex) {return ss.last();}}}// SynchronizedList 也是内部通过 synchronized 实现线程安全static class SynchronizedRandomAccessList<E>extends SynchronizedList<E>implements RandomAccess {SynchronizedRandomAccessList(List<E> list) {super(list);}SynchronizedRandomAccessList(List<E> list, Object mutex) {super(list, mutex);}public List<E> subList(int fromIndex, int toIndex) {synchronized (mutex) {return new SynchronizedRandomAccessList<>(list.subList(fromIndex, toIndex), mutex);}}private static final long serialVersionUID = 1530674583602358482L;/*** Allows instances to be deserialized in pre-1.4 JREs (which do* not have SynchronizedRandomAccessList). SynchronizedList has* a readResolve method that inverts this transformation upon* deserialization.*/private Object writeReplace() {return new SynchronizedList<>(list);}}// 其他的也是一样的原理 此处不在赘述// 下面再看几个方法// 获取 SynchronizedCollection对象public static <T> Collection<T> synchronizedCollection(Collection<T> c) {return new SynchronizedCollection<>(c);}// 返回线程安全的listpublic static <T> List<T> synchronizedList(List<T> list) {return (list instanceof RandomAccess ?new SynchronizedRandomAccessList<>(list) :new SynchronizedList<>(list));}// 返回线程安全的Mappublic static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {return new SynchronizedMap<>(m);}// 其他的也是一样的原理 此处不在赘述// 返回一个 空Listpublic static final <T> List<T> emptyList() {return (List<T>) EMPTY_LIST;}public static final List EMPTY_LIST = new EmptyList<>();private static class EmptyList<E>extends AbstractList<E>implements RandomAccess, Serializable {private static final long serialVersionUID = 8842843931221139166L;public Iterator<E> iterator() {return emptyIterator();}public ListIterator<E> listIterator() {return emptyListIterator();}public int size() {return 0;}public boolean isEmpty() {return true;}public boolean contains(Object obj) {return false;}public boolean containsAll(Collection<?> c) { return c.isEmpty(); }public Object[] toArray() { return new Object[0]; }public <T> T[] toArray(T[] a) {if (a.length > 0)a[0] = null;return a;}public E get(int index) {throw new IndexOutOfBoundsException("Index: "+index);}public boolean equals(Object o) {return (o instanceof List) && ((List<?>)o).isEmpty();}public int hashCode() { return 1; }@Overridepublic boolean removeIf(Predicate<? super E> filter) {Objects.requireNonNull(filter);return false;}@Overridepublic void replaceAll(UnaryOperator<E> operator) {Objects.requireNonNull(operator);}@Overridepublic void sort(Comparator<? super E> c) {}// Override default methods in Collection@Overridepublic void forEach(Consumer<? super E> action) {Objects.requireNonNull(action);}@Overridepublic Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); }// Preserves singleton propertyprivate Object readResolve() {return EMPTY_LIST;}}// 其他方法类似于此// 返回指定列表的一个动态类型安全视图public static <E> List<E> checkedList(List<E> list, Class<E> type) {return (list instanceof RandomAccess ?new CheckedRandomAccessList<>(list, type) :new CheckedList<>(list, type));}// 其他方法类似于此}
总结
从源码我们可以看出来,Collections 类提供了很多操作集合的方法
- 尤其是在Java集合框架中不是线程安全的如HashSet、HashMap、ArratList、LinkedList等
- 但是也可以使用JUC下的线程安全的集合框架
