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 异常,这些在下一篇文章中详细介绍。

java 集合之 Collections.UnmodifiableXXX 与 Collections.synchronizedXXX相关推荐

  1. JAVA集合框架工具类自定义Collections集合方法

    项目中有需要多次统计 某些集合中 的某个属性值,所以考虑封装一个方法,让其其定义实现计算方式. 话不多说,看代码: 1.封装的自定义集合工具类:CollectionsCustom [Java] 纯文本 ...

  2. Java集合框架:Collections工具类

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  3. java集合学习笔记 ---Collections类对集合的处理

    2019独角兽企业重金招聘Python工程师标准>>> 包名:java.util.Collections Collections是个类,不是接口 有以下方法,部分列举 1.对List ...

  4. Java集合(8)--集合工具类Collections

    Collections 是一个操作 Set.List 和 Map 等集合的工具类. Collections 中提供了一系列静态的方法对集合元素进行排序.查询和修改等操作,还提供了对集合对象设置不可变. ...

  5. Java——操作集合的工具类:Collections

    Java 提供了一个操作 Set .List 和 Map 等集合的工具类 :Collections,该工具类里提供了大量方法对集合元素进行排序.查询和修改等操作 转载于:https://www.cnb ...

  6. Java集合工具类:Collections

    Java提供了一个操作Set.List和Map等集合的工具类:Collections,该工具类里 提供了大量方法对集合元素进行排序.查询和修改等操作,还提供了对集合对象实现同步控制等方法. 一. 排序 ...

  7. java基础集合操作工具类Collections简述(java集合四)

    对集合中的元素进行排序 Collections中的sort方法使用 public class ListDemo {public static void main(String[] args) {Lis ...

  8. java 集合操作工具包_java之操作集合的工具类--Collections

    Collections是一个操作Set.List和Map等集合的工具类. Collections中提供了大量方法对集合元素进行排序.查询和修改等操作,还提供了对集合对象设置不可变.对集合对象实现同步控 ...

  9. java集合中取最大值_Java后台通过Collections获取list集合中最大数,最小数代码

    我就废话不多说了,大家还是直接看代码吧~ package com.jalor; import java.util.ArrayList; import java.util.Collections; im ...

最新文章

  1. 中原银行 Arthas 实践之路
  2. 艾媒咨询:泛娱乐「体验共享」报告发布,网易云信多个案例领衔
  3. 使用sysbench对mysql压力测试
  4. iconfont 图标转为字体_iconfont字体图标的使用方法--超简单!
  5. 数据结构之树的一些基本操作
  6. Symbian中不能跨越线程(RThread)使用的对象/组件(RSocket/Memery Heap,etc)
  7. 高龄申请海外计算机科学博士,【原创】牛津在读小博谈谈在海外攻读生命科学专业的一些心得...
  8. linux模块导出符号 EXPORT_SYMBOL_GPLEXPORT_SYMBOL(转)
  9. 关于Linux不能ping通外网的解决方法
  10. CentOS 快速安装ftp
  11. js文件之间函数的调用
  12. java单线程爬虫使用Jsoup爬取bt磁力链接
  13. [升级凯立德地图] 升级凯立德地图 (车载 导航仪)
  14. android webview打开pdf文件
  15. hbase scan超时设置_hbase scan limit 10
  16. 文本表示(Representation)
  17. bzoj 4453 cys就是要拿英魂! —— 后缀数组+单调栈+set
  18. SQLyog使用错误号码2058
  19. 计算机搜索不到网络扫描仪,XP系统我的电脑找不到扫描仪和摄像头如何解决
  20. 字节还能如何“跳动”

热门文章

  1. ISkyShop B2B2C 商城系统V1.0正式版隆重发布
  2. 【实例分割】1、SOLOv1: Segmenting Objects by Locations_2019
  3. Python语言被广泛用在哪些领域了?
  4. x265源码分析 main函数 x265.cpp
  5. 区块链信用机制与应用场景介绍
  6. app四种开发模式区别,网页链接转app优缺点
  7. 【linux进阶2】linux的高级存储管理(lvm卷的扩展和缩减)
  8. 一个在线jpg png转ICO的网站
  9. CodeForces612AThe Text Splitting(模拟,暴力枚举)
  10. Java 在CS客户端做网页连接