1.sort(List), sort(List, Comparator)方法:对集合进行排序,列表中元素需要实现Comparable接口;前者使用Collection自然比较法,后者采用自定义的比较方法
源码:
public static <T extends Comparable<? super T>> void sort(List<T> list) {
list.sort(null);
}
public static <T> void sort(List<T> list, Comparator<? super T> c) {
list.sort(c);
}
例:
public static void main (String args[]) {
// 1.sort方法
List list = new ArrayList();
list.add("h");
list.add("e");
list.add("l");
list.add("l");
list.add("o");
System.out.println(list);
Collections.sort(list);
System.out.println(list);
}
结果:
[h, e, l, l, o]
[e, h, l, l, o]
2.binarySearch(List,Object), binarySearch(List,Object, Comparator)方法:查找指定元素在集合中的位置,前者在算法比较时采用自然比较法,后者采用自定义的比较方法
源码:关于为什么要用不同的迭代方法可以看RandomAccess详解
算法思想: 先取集合中间的元素和指定元素进行比较,如果大于就说明指定元素在前半段,然后再拿前半段的中间元素和指定元素比较,以此循环直到找到index
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);
else
return 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;
else
return 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;
else
return mid; // key found
}
return -(low + 1); // key not found
}
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;
}
例:
// 3.binarySearch方法
List list2 = new ArrayList();
list2.add("h");
list2.add("e");
list2.add("l");
list2.add("l");
list2.add("o");
System.out.println(Collections.binarySearch(list2, "o"));
System.out.println(Collections.binarySearch(list2, "l"));
结果:可以看出,如果列表中如果有重复元素,返回的是第一个元素的位置
4
2
3.reverse()方法:反转集合中元素顺序
源码:
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 method
ListIterator 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);
}
}
}
例:
// 2.reverse方法
List list1 = new ArrayList();
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
System.out.println(list1);
Collections.reverse(list1);
System.out.println(list1);
结果:
[1, 2, 3, 4]
[4, 3, 2, 1]
4.shuffle(collection), shuffle(Collection,Random)方法:对集合进行随机排序,前者使用自然比较,后者采用自定义的Random
源码:通过swap方法及Random的随机数方法,对2个位置的元素随机交换
public static void shuffle(List<?> list, Random rnd) {
int size = list.size();
if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
for (int i=size; i>1; i--)
swap(list, i-1, rnd.nextInt(i));
} else {
Object arr[] = list.toArray();
// Shuffle array
for (int i=size; i>1; i--)
swap(arr, i-1, rnd.nextInt(i));
// Dump array back into list
// instead of using a raw type here, it's possible to capture
// the wildcard but it will require a call to a supplementary
// private method
ListIterator it = list.listIterator();
for (int i=0; i<arr.length; i++) {
it.next();
it.set(arr[i]);
}
}
}
例:
List list4 = new ArrayList();
list4.add("h");
list4.add("e");
list4.add("l");
list4.add("l");
list4.add("o");
System.out.println(list4);
Collections.shuffle(list4);
System.out.println(list4);
结果:
[h, e, l, l, o]
[l, l, e, h, o]
5.swap(Collection/Object[],int,int)方法:交换集合/数组中指定元素索引的位置
源码:
public static void swap(List<?> list, int i, int j) {
// instead of using a raw type here, it's possible to capture
// the wildcard but it will require a call to a supplementary
// private method
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;
}
例:
List list3 = new ArrayList();
list3.add("h");
list3.add("e");
list3.add("l");
list3.add("l");
list3.add("o");
System.out.println(list3);
Collections.swap(list3, 1,4);
System.out.println(list3);
结果:
[h, e, l, l, o]
[h, o, l, l, e]
6.fill(Collection,Object)方法:用某个对象替换集合中所有元素
源码:
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);
}
}
}
例:
List list5 = new ArrayList();
list5.add("h");
list5.add("e");
list5.add("l");
System.out.println(list5);
Collections.fill(list5, "a");
System.out.println(list5);
}
结果:
[h, e, l]
[a, a, a]
7.copy(List a,List b)方法:将集合b中的元素全部复制到a中,并且覆盖相应索引的元素
源码:b长度要小于等于a
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());
}
}
}
例:
List listA = new ArrayList();
listA.add("h");
listA.add("e");
listA.add("l");
List listB = new ArrayList();
listB.add("a");
listB.add("a");
System.out.println(listA);
Collections.copy(listA, listB);
System.out.println(listA);
结果:
[h, e, l]
[a, a, l]
8.min(Collection),min(Collection, Comparator), max(Collection),max(Collection, Comparator)方法:找出集合中最小/大的元素,前者使用Collection自然比较法,后者采用自定义的Comparator比较
源码:从第一个开始,一个一个地往后比较
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> T min(Collection<? extends T> coll, Comparator<? super T> comp) {
if (comp==null)
return (T)min((Collection) coll);
Iterator<? extends T> i = coll.iterator();
T candidate = i.next();
while (i.hasNext()) {
T next = i.next();
if (comp.compare(next, 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 <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) {
if (comp==null)
return (T)max((Collection) coll);
Iterator<? extends T> i = coll.iterator();
T candidate = i.next();
while (i.hasNext()) {
T next = i.next();
if (comp.compare(next, candidate) > 0)
candidate = next;
}
return candidate;
}
例:
List list6 = new ArrayList();
list6.add("h");
list6.add("e");
list6.add("l");
list6.add("l");
list6.add("o");
System.out.println(Collections.min(list6));
System.out.println(Collections.max(list6));
结果:
e
o
9.rotate(List, int) 方法:将集合中的元素向右移动指定位,超长的元素循环到元素的最前方,正数向右移,负数向左移
源码:
算法: 随机访问List的算法是用循环用原来位置上的元素替换新位置上的元素;链表算法是先取移位后不需要前置的元素的长度,1.将这部分元素进行翻转;2.将剩余部分元素进行翻转;3.整体进行翻转
public static void rotate(List<?> list, int distance) {
if (list instanceof RandomAccess || list.size() < ROTATE_THRESHOLD)
rotate1(list, distance);
else
rotate2(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);
}
例:
List list7 = new ArrayList();
list7.add("h");
list7.add("e");
list7.add("l");
list7.add("l");
list7.add("o");
System.out.println(list7);
Collections.rotate(list7, 2);
System.out.println(list7);
结果:
[h, e, l, l, o]
[l, o, h, e, l]
10.replaceAll(List,Object,Object)方法:替换指定元素为新元素,如果替换成功返回true否则返回false
源码:
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;
}
例:
List list8 = new ArrayList();
list8.add("h");
list8.add("e");
list8.add("l");
list8.add("l");
list8.add("o");
System.out.println(list8);
System.out.println(Collections.replaceAll(list8, "l", "a"));
System.out.println(list8);
结果:
[h, e, l, l, o]
true
[h, e, a, a, o]
11.indexOfSubList(List a,List b),lastIndexOfSubList(List a,List b)方法:查找b在a中首次出现位置的索引。
源码:使用嵌套for循环来查找内容。每当匹配到一致的元素时,开始新的一轮外层循环
public 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 cand
return candidate; // All elements of candidate matched target
}
} else { // Iterator version of above algorithm
ListIterator<?> 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 candidate
for (int j=0; j<i; j++)
si.previous();
continue nextCand;
}
}
return candidate;
}
}
return -1; // No candidate matched the target
}
public 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 version
nextCand:
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 cand
return candidate; // All elements of candidate matched target
}
} else { // Iterator version of above algorithm
if (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 candidate
for (int j=0; j<=i+1; j++)
si.previous();
}
continue nextCand;
}
}
return candidate;
}
}
return -1; // No candidate matched the target
}
测试:
List<String> source = Arrays.asList("hello".split(""));
List<String> targetA = Arrays.asList("el".split(""));
List<String> targetB = Arrays.asList("aaaaaahe".split(""));
List<String> targetC = Arrays.asList("ko".split(""));
System.out.println(Collections.indexOfSubList(source, targetA));
System.out.println(Collections.indexOfSubList(source, targetB));
System.out.println(Collections.indexOfSubList(source, targetC));
结果:b需要是a的子集
1
-1
-1