天津电子商务网站建设/郑州seo联系搜点网络效果好
java 中提供了一系列的创建不可变集合的方法 和 创建同步集合的方法。下面进行简单的介绍。
一、UnmodifiableXXX 不可变集合
1、 实现原理
下面以 UnmodifiableList 为例来进行说明。
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();}@Overridepublic void replaceAll(UnaryOperator<E> operator) {throw new UnsupportedOperationException();}@Overridepublic 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();}@Overridepublic void forEachRemaining(Consumer<? super E> action) {i.forEachRemaining(action);}};}public List<E> subList(int fromIndex, int toIndex) {return new UnmodifiableList<>(list.subList(fromIndex, toIndex));}/*** UnmodifiableRandomAccessList instances are serialized as* UnmodifiableList instances to allow them to be deserialized* in pre-1.4 JREs (which do not have UnmodifiableRandomAccessList).* This method inverts the transformation. As a beneficial* side-effect, it also grafts the RandomAccess marker onto* UnmodifiableList instances that were serialized in pre-1.4 JREs.** Note: Unfortunately, UnmodifiableRandomAccessList instances* serialized in 1.4.1 and deserialized in 1.4 will become* UnmodifiableList instances, as this method was missing in 1.4.*/private Object readResolve() {return (list instanceof RandomAccess? new UnmodifiableRandomAccessList<>(list): this);}}
UnmodifiableList 继承 UnmodifiableCollection类,UnmodifiableCollection 中涉及到元素改动(新增、删除、清空…)的方法都直接抛出 UnsupportedOperationException 异常,并不改动元素;Iterator 中涉及到元素修改的方法也一样不进行元素的改动。
static class UnmodifiableCollection<E> implements Collection<E>, Serializable {private static final long serialVersionUID = 1820017752578914078L;final Collection<? extends E> c;UnmodifiableCollection(Collection<? extends E> c) {if (c==null)throw new NullPointerException();this.c = c;}public int size() {return c.size();}public boolean isEmpty() {return c.isEmpty();}public boolean contains(Object o) {return c.contains(o);}public Object[] toArray() {return c.toArray();}public <T> T[] toArray(T[] a) {return c.toArray(a);}public String toString() {return c.toString();}public Iterator<E> iterator() {return new Iterator<E>() {private final Iterator<? extends E> i = c.iterator();public boolean hasNext() {return i.hasNext();}public E next() {return i.next();}public void remove() {throw new UnsupportedOperationException();}@Overridepublic void forEachRemaining(Consumer<? super E> action) {// Use backing collection versioni.forEachRemaining(action);}};}public boolean add(E e) {throw new UnsupportedOperationException();}public boolean remove(Object o) {throw new UnsupportedOperationException();}public boolean containsAll(Collection<?> coll) {return c.containsAll(coll);}public boolean addAll(Collection<? extends E> coll) {throw new UnsupportedOperationException();}public boolean removeAll(Collection<?> coll) {throw new UnsupportedOperationException();}public boolean retainAll(Collection<?> coll) {throw new UnsupportedOperationException();}public void clear() {throw new UnsupportedOperationException();}// Override default methods in Collection@Overridepublic void forEach(Consumer<? super E> action) {c.forEach(action);}@Overridepublic boolean removeIf(Predicate<? super E> filter) {throw new UnsupportedOperationException();}@SuppressWarnings("unchecked")@Overridepublic Spliterator<E> spliterator() {return (Spliterator<E>)c.spliterator();}@SuppressWarnings("unchecked")@Overridepublic Stream<E> stream() {return (Stream<E>)c.stream();}@SuppressWarnings("unchecked")@Overridepublic Stream<E> parallelStream() {return (Stream<E>)c.parallelStream();}}
UnmodifiableList 中对 UnmodifiableCollection 中一些方法根据自身需求进行了覆盖,保持元素不可变的实现方式与UnmodifiableCollection一样。
2、使用
List<String> list = new ArrayList<String>();
list.add("aa");
list.add("bb");List<String> unmodifiableList = Collections.unmodifiableList(list);
System.out.println(unmodifiableList);//[aa, bb]
当我们调用 当unmodifiableList.add(“add”)时,运行代码将会出现以下异常:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableCollection.add(Collections.java:1018)
at com.wyp.test.testFiles(test.java:152)
at com.wyp.test.main(test.java:160)
然而 Collections.unmodifiableList(…) 实现的不是真正的不可变集合,当原始集合被修改后,不可变集合里面的元素也是跟着发生变化。
在上述代码的下面加入以下代码:
list.add("cc");System.out.println(unmodifiableList);
再次打印unmodifiableList的时候,你会发现结果是[aa, bb, cc],多了一个"cc"元素
Collections.synchronizedXXX 同步集合
1、实现
先来看一下同步集合的共同父类的实现。
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();}}}
这里在构造函数中初始化了一个对象锁 mutex ,并使用这个锁来使用同步代码块对相关操作进行同步控制。
下来再来看看 SynchronizedList 的实现(SynchronizedSet, SynchronizedMap 等的实现与之类似)
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);}}@Overridepublic void replaceAll(UnaryOperator<E> operator) {synchronized (mutex) {list.replaceAll(operator);}}@Overridepublic void sort(Comparator<? super E> c) {synchronized (mutex) {list.sort(c);}}// ....}
SynchronizedList 继承SynchronizedCollection类,实现了List接口,以组合的方式包含了 final 的 List 成员变量。相关的方法中使用 父类中的 mutex 锁进行同步控制,这样就可以避免子类和父类很相互锁住对方。
需要注意的是,iterator 方法并没有使用 mutex 进行同步控制,需要客户端自行进行同步控制。
2、使用
使用方式很简单,Collections.synchronizedList(list) 这样就可以
注:同步容器在有些情况下不是线程安全的,同步容易的迭代器可能会抛出 ConcurrentModificationException 异常,这些在下一篇文章中详细介绍。