目录:
Collections的sort
Collections的search
Collections的reverse
Collections的shuffle
Collections的swap
Collections的fill
Collections的copy
Collections的min和max
Collections的rotate
Collections的Unmodifiable
Collections的Synchronized
1. Collections的sort
对集合元素进行排序。
1.1 使用
private static void testSort() {
List<Integer> list = new ArrayList<>();
Random random = new Random();
for (int i = 0; i < 20; i++) {
list.add(random.nextInt(20));
}
Collections.sort(list);
System.out.println(Arrays.toString(list.toArray()));
}
执行输出:[0, 0, 1, 3, 3, 3, 4, 6, 7, 8, 8, 10, 10, 10, 12, 14, 14, 17, 19, 19],默认是按照升序排列的。
我们可以传入一个外比较器:
private static void testSortComparator() {
List<Integer> list = new ArrayList<>();
Random random = new Random();
for (int i = 0; i < 20; i++) {
list.add(random.nextInt(20));
}
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
System.out.println(Arrays.toString(list.toArray()));
}
执行输出:[19, 19, 19, 18, 16, 16, 15, 14, 14, 13, 13, 12, 12, 10, 8, 8, 8, 7, 7, 2],这样就实现了倒序排列。
1.2 实现原理
@SuppressWarnings({"unchecked", "rawtypes"})
public static <T> void sort(List<T> list, Comparator<? super T> c) {
list.sort(c);
}
@SuppressWarnings({"unchecked", "rawtypes"})
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
第一步,先将集合转换成数组。
第二步,对数组做排序。
第三步,再重新将数组的值赋给集合。
对数组排序的过程使用的是Arrays.sort(Object[]),内部实现是:
在jdk1.7之后,Arrays类中的sort方法有一个分支判断,当LegacyMergeSort.userRequested为true的情况下,采用legacyMergeSort,否则采用ComparableTimSort。并且在legacyMergeSort的注释上标明了该方法会在以后的jdk版本中废弃,因此以后Arrays类中的sort方法将采用ComparableTimSort类中的sort方法。
具体可以看我的上一篇文章:《Java篇 - Arrays的使用和实现》https://blog.csdn.net/u014294681/article/details/86265920
2. Collections的search
对集合进行查找,和数组一样,查找使用的是二分查找,也可以传入外比较器,待查找的集合需要本身有序,否则查找出来的下标将不准。
2.1 使用
private static void testSearch() {
List<Integer> list = new ArrayList<>();
Random random = new Random();
for (int i = 0; i < 20; i++) {
list.add(random.nextInt(20));
}
System.out.println(Arrays.toString(list.toArray()));
System.out.println("search 10 index = " + Collections.binarySearch(list, 10));
}
此时,集合是无序的,这时查找输出:
[8, 6, 4, 18, 10, 19, 18, 13, 19, 0, 12, 6, 11, 1, 17, 10, 8, 3, 18, 18]
search 10 index = -13
我们先对集合排序再查找:
private static void testSearch() {
List<Integer> list = new ArrayList<>();
Random random = new Random();
for (int i = 0; i < 20; i++) {
list.add(random.nextInt(20));
}
Collections.sort(list);
System.out.println(Arrays.toString(list.toArray()));
System.out.println("search 10 index = " + Collections.binarySearch(list, 10));
}
执行输出:
[0, 0, 0, 3, 4, 6, 7, 7, 10, 10, 11, 11, 11, 14, 16, 16, 17, 18, 18, 19]
search 10 index = 9
2.2 实现原理
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
}
可以看到,就是二分查找的实现,这边就不再赘述,上一篇文章中有分析。
3. Collections的reverse
对集合数据进行反转。
3.1 使用
private static void testReverse() {
List<Integer> list = new ArrayList<>();
Random random = new Random();
for (int i = 0; i < 20; i++) {
list.add(random.nextInt(20));
}
System.out.println("origin = " + Arrays.toString(list.toArray()));
Collections.reverse(list);
System.out.println("reverse = " + Arrays.toString(list.toArray()));
}
执行输出:
origin = [6, 2, 14, 11, 16, 15, 15, 7, 15, 2, 0, 7, 16, 12, 16, 7, 15, 2, 6, 17]
reverse = [17, 6, 2, 15, 7, 16, 12, 16, 7, 0, 2, 15, 7, 15, 15, 16, 11, 14, 2, 6]
3.2 实现原理
private static final int REVERSE_THRESHOLD = 18;
@SuppressWarnings({"rawtypes", "unchecked"})
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 {
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);
}
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
public static void swap(List<?> list, int i, int j) {
final List l = list;
l.set(i, l.set(j, l.get(i)));
}
第一步,判断集合大小是否小于REVERSE_THRESHOLD或者集合为随机访问类型,如果是,则从左右以中间位置为基准做交换,如果不是则走第二步。
第二步,用两个迭代器,一个正序,一个倒序,从开始位置到中间位置,用两个迭代器互相交换值。
4. Collections的shuffle
shuffle的意思是洗牌,打乱,顾名思义,就是把集合元素打乱。
4.1 使用
private static void testShuffle() {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
list.add(i);
}
System.out.println("origin = " + Arrays.toString(list.toArray()));
Collections.shuffle(list);
System.out.println("shuffle = " + Arrays.toString(list.toArray()));
}
执行输出:
origin = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
shuffle = [2, 15, 6, 14, 18, 5, 17, 16, 1, 3, 9, 7, 11, 13, 8, 4, 12, 10, 19, 0]
4.2 实现原理
private static Random r;
private static final int SHUFFLE_THRESHOLD = 5;
public static void shuffle(List<?> list) {
Random rnd = r;
if (rnd == null)
r = rnd = new Random();
shuffle(list, rnd);
}
@SuppressWarnings({"rawtypes", "unchecked"})
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();
for (int i=size; i>1; i--)
swap(arr, i-1, rnd.nextInt(i));
ListIterator it = list.listIterator();
for (int i=0; i<arr.length; i++) {
it.next();
it.set(arr);
}
}
}
第一步,判断Random是否已经实例化(懒加载),如果没有,则构造一个随机对象。
第二步,判断集合大小是否小于SHUFFLE_THRESHOLD或者集合为随机访问类型,如果是,则调用swap函数随机交换集合元素,如果不是则走第三步。
第三步,将集合转换成数组,然后随机交换数组元素。
第四步,将打乱好的数组重新赋值给集合。
5. Collections的swap
将集合中两个位置的元素进行交换。
5.1 使用
private static void testSwap() {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
list.add(i);
}
System.out.println("origin = " + Arrays.toString(list.toArray()));
Collections.swap(list, 1, 10);
System.out.println("swap = " + Arrays.toString(list.toArray()));
}
执行输出:
origin = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
swap = [0, 10, 2, 3, 4, 5, 6, 7, 8, 9, 1, 11, 12, 13, 14, 15, 16, 17, 18, 19]
5.2 实现原理
@SuppressWarnings({"rawtypes", "unchecked"})
public static void swap(List<?> list, int i, int j) {
final List l = list;
l.set(i, l.set(j, l.get(i)));
}
原理很简单,不赘述了。
6. Collections的fill
将集合的元素全部填充为某个值。
6.1 使用
private static void testFill() {
List<Integer> list = new ArrayList<>();
System.out.println("origin = " + Arrays.toString(list.toArray()));
Collections.fill(list, 1);
System.out.println("fill = " + Arrays.toString(list.toArray()));
}
执行输出:
origin = []
fill = []
这点要注意,集合和数组不一样,数组是初始化之后就会分配一块连续的内容。而集合的实现有很多种,上面用到ArrayList,它重写的Collection的size()方法是它实际存储的元素个数。而Collections fill元素的时候是以这个size作为边界结点来赋值的。
改一下代码:
private static void testFill() {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
list.add(i);
}
System.out.println("origin = " + Arrays.toString(list.toArray()));
Collections.fill(list, 1);
System.out.println("fill = " + Arrays.toString(list.toArray()));
}
执行输出:
origin = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
fill = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
6.2 实现原理
private static final int FILL_THRESHOLD = 25;
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);
}
}
}
第一步,判断集合的size是否小于FILL_THRESHOLD或者集合为随机访问类型,如果是,则遍历集合进行赋值,如果不是则走第二步。
第二步,获取集合迭代器,然后遍历集合用迭代器进行赋值。
7. Collections的copy
将一个集合的元素拷贝到另一个集合。
7.1 使用
private static void testCopy() {
List<Integer> source = new ArrayList<>();
for (int i = 0; i < 20; i++) {
source.add(i);
}
System.out.println("source = " + Arrays.toString(source.toArray()));
int size = source.size();
List<Integer> dest = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
dest.add(1);
}
System.out.println("origin dest = " + Arrays.toString(dest.toArray()));
Collections.copy(dest, source);
System.out.println("dest dest = " + Arrays.toString(dest.toArray()));
}
注意,目标集合的size不能小于源集合的size(这边是ArrayList,size为实际存储元素的个数),否则会报IndexOutOfBoundsException("Source does not fit in dest")。
执行输出:
source = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
origin dest = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
dest dest = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
7.2 实现原理
private static final int COPY_THRESHOLD = 10;
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());
}
}
}
第一步,边界校验,目标集合的size必须大于源集合的size,否则抛出异常。
第二步, 判断源集合的size是否小于COPY_THRESHOLD或者源集合与目标集合都为随机访问类型,如果是,则直接循环设置。如果不是,则走第三步。
第三步,拿到源集合和目标集合的迭代器,然后用迭代器遍历设置元素。
8. Collections的min和max
获取集合中元素的最小值或最大值。
8.1 使用
private static void testMinOrMax() {
List<Integer> list = new ArrayList<>();
Random random = new Random();
for (int i = 0; i < 20; i++) {
list.add(random.nextInt(20));
}
System.out.println("list = " + Arrays.toString(list.toArray()));
System.out.println("min = " + Collections.min(list));
System.out.println("max = " + Collections.max(list));
}
可以看到,我这边的集合元素是随机生成的,集合中的元素并不是排好序的。
执行输出:
list = [15, 5, 0, 14, 8, 1, 8, 15, 10, 18, 7, 19, 12, 16, 4, 9, 3, 16, 19, 6]
min = 0
max = 19
8.2 实现原理
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;
}
上面代码很明显,就是遍历集合,找出最大或最小值。
9. Collections的rotate
对集合进行旋转,rotate是将集合旋转一定的distance,分为正方向和反方向旋转,看传入的distance的正负。
9.1 使用
private static void testRotate() {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
list.add(i);
}
System.out.println("list = " + Arrays.toString(list.toArray()));
Collections.rotate(list, -5);
System.out.println("rotate -5 = " + Arrays.toString(list.toArray()));
Collections.rotate(list, 5);
System.out.println("rotate 5 = " + Arrays.toString(list.toArray()));
}
执行输出:
list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
rotate -5 = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4]
rotate 5 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
9.2 实现原理
private static final int ROTATE_THRESHOLD = 100;
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);
}
1. 如果集合size小于ROTATE_THRESHOLD或者集合类型为随机访问类型则进入到rotate1分支,否则进入到rotate2分支。
2. 进入rotate1分支,对于rotate1的实现具体的做法是,将序列的第一个元素交换至正确的位置i,此时原来在位置i的元素就是一个错误放置的元素displaced,然后计算该元素正确放置的位置i,并将其放置到位置i,此时又得到一个错误放置的元素displaced,重复此过程直到错误放置的元素displaced被放置到了第一个位置(即i == 0)。
3. 进入rotate2分支,对于rotate2的实现与上面的实现完全不一样,因为考虑到rotate2适用于的是类似于采用链表存储的List,因此不具有随机访问的特性。因此该实现采用的是将原list在-distance mod size处使用subList方法拆分为两个子列表s1,s2,并分别反转俩链表revese(s1),reverse(s2),最后再将整个链表反转。
10. Collections的Unmodifiable
传入一个集合,生成一个不可修改的集合。
10.1 使用
private static void testUnmodifiable() {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
list.add(i);
}
List<Integer> result = Collections.unmodifiableList(list);
result.remove(0);
}
执行抛出:Exception in thread "main" java.lang.UnsupportedOperationException
除了Collections.unmodifiableList,还有如下这些相似的方法:
public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c)
public static <T> Set<T> unmodifiableSet(Set<? extends T> s)
public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s)
public static <T> NavigableSet<T> unmodifiableNavigableSet(NavigableSet<T> s)
public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m)
public static <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K, ? extends V> m)
public static <K,V> NavigableMap<K,V> unmodifiableNavigableMap(NavigableMap<K, ? extends V> m)
10.2 实现原理
以Collections.unmodifiableList(list)为例:
public static <T> List<T> unmodifiableList(List<? extends T> list) {
return (list instanceof RandomAccess ?
new UnmodifiableRandomAccessList<>(list) :
new UnmodifiableList<>(list));
}
static class UnmodifiableList<E> extends UnmodifiableCollection<E>
implements List<E> {
private static final long serialVersionUID = -283967356065247728L;
final List<? extends E> list;
UnmodifiableList(List<? extends E> list) {
super(list);
this.list = list;
}
public boolean equals(Object o) {return o == this || list.equals(o);}
public int hashCode() {return list.hashCode();}
public E get(int index) {return list.get(index);}
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
public int indexOf(Object o) {return list.indexOf(o);}
public int lastIndexOf(Object o) {return list.lastIndexOf(o);}
public boolean addAll(int index, Collection<? extends E> c) {
throw new UnsupportedOperationException();
}
@Override
public void replaceAll(UnaryOperator<E> operator) {
throw new UnsupportedOperationException();
}
@Override
public void sort(Comparator<? super E> c) {
throw new UnsupportedOperationException();
}
public ListIterator<E> listIterator() {return listIterator(0);}
public ListIterator<E> listIterator(final int index) {
return new ListIterator<E>() {
private final ListIterator<? extends E> i
= list.listIterator(index);
public boolean hasNext() {return i.hasNext();}
public E next() {return i.next();}
public boolean hasPrevious() {return i.hasPrevious();}
public E previous() {return i.previous();}
public int nextIndex() {return i.nextIndex();}
public int previousIndex() {return i.previousIndex();}
public void remove() {
throw new UnsupportedOperationException();
}
public void set(E e) {
throw new UnsupportedOperationException();
}
public void add(E e) {
throw new UnsupportedOperationException();
}
@Override
public void forEachRemaining(Consumer<? super E> action) {
i.forEachRemaining(action);
}
};
}
public List<E> subList(int fromIndex, int toIndex) {
return new UnmodifiableList<>(list.subList(fromIndex, toIndex));
}
private Object readResolve() {
return (list instanceof RandomAccess
? new UnmodifiableRandomAccessList<>(list)
: this);
}
}
static class UnmodifiableRandomAccessList<E> extends UnmodifiableList<E>
implements RandomAccess
{
UnmodifiableRandomAccessList(List<? extends E> list) {
super(list);
}
public List<E> subList(int fromIndex, int toIndex) {
return new UnmodifiableRandomAccessList<>(
list.subList(fromIndex, toIndex));
}
private static final long serialVersionUID = -2542308836966382001L;
private Object writeReplace() {
return new UnmodifiableList<>(list);
}
}
可以看到原理很简单,属于装饰器模式,将一个集合包装成一个不可修改的集合:读方法调用传入集合的读方法,写方法直接抛出异常。
11. Collections的Synchronized
将一个普通集合转换成同步集合,但是不推荐这种方式,因为它的锁粒度很大,属于锁全局,具体的可以看看我之前关于同步并发的文章。
11.1 使用
private static void testSynchronized() {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
list.add(i);
}
list = Collections.synchronizedList(list);
}
这样,该集合就能在多线程下保持读写安全了。
除了Collections.synchronizedList(list),还有如下这些相似的方法:
public static <T> Collection<T> synchronizedCollection(Collection<T> c)
public static <T> Set<T> synchronizedSet(Set<T> s)
public static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s)
public static <T> NavigableSet<T> synchronizedNavigableSet(NavigableSet<T> s)
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)
public static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)
public static <K,V> NavigableMap<K,V> synchronizedNavigableMap(NavigableMap<K,V> m)
11.2 实现原理
以Collections.synchronizedList(list)为例:
public static <T> List<T> synchronizedList(List<T> list) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<>(list) :
new SynchronizedList<>(list));
}
static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E> {
private static final long serialVersionUID = -7754090372962971524L;
final List<E> list;
SynchronizedList(List<E> list) {
super(list);
this.list = list;
}
SynchronizedList(List<E> list, Object mutex) {
super(list, mutex);
this.list = list;
}
public boolean equals(Object o) {
if (this == o)
return true;
synchronized (mutex) {return list.equals(o);}
}
public int hashCode() {
synchronized (mutex) {return list.hashCode();}
}
public E get(int index) {
synchronized (mutex) {return list.get(index);}
}
public E set(int index, E element) {
synchronized (mutex) {return list.set(index, element);}
}
public void add(int index, E element) {
synchronized (mutex) {list.add(index, element);}
}
public E remove(int index) {
synchronized (mutex) {return list.remove(index);}
}
public int indexOf(Object o) {
synchronized (mutex) {return list.indexOf(o);}
}
public int lastIndexOf(Object o) {
synchronized (mutex) {return list.lastIndexOf(o);}
}
public boolean addAll(int index, Collection<? extends E> c) {
synchronized (mutex) {return list.addAll(index, c);}
}
public ListIterator<E> listIterator() {
return list.listIterator(); // Must be manually synched by user
}
public ListIterator<E> listIterator(int index) {
return list.listIterator(index); // Must be manually synched by user
}
public List<E> subList(int fromIndex, int toIndex) {
synchronized (mutex) {
return new SynchronizedList<>(list.subList(fromIndex, toIndex),
mutex);
}
}
@Override
public void replaceAll(UnaryOperator<E> operator) {
synchronized (mutex) {list.replaceAll(operator);}
}
@Override
public void sort(Comparator<? super E> c) {
synchronized (mutex) {list.sort(c);}
}
private Object readResolve() {
return (list instanceof RandomAccess
? new SynchronizedRandomAccessList<>(list)
: this);
}
}
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;
private Object writeReplace() {
return new SynchronizedList<>(list);
}
}
可以看到,也是装饰器模式,将一个普通集合的所有方法一股脑用synchronized包装起来。
---------------------
【转载,仅作分享,侵删】
作者:况众文
原文:https://blog.csdn.net/u014294681/article/details/86310680
版权声明:本文为博主原创文章,转载请附上博文链接!
|
|