2.2 Java.util.Collctions

这个类中的方法实在是太长了,挑一些经典的,面试也常常问道的问题出来讲讲!

2.2.1 为什么Collections中的静态方法可以让一个非线程安全的集合变成线程安全呢?

以synchronizedMap(Map<K,V> m)方法为例:

  public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {return new SynchronizedMap<>(m);}private static class SynchronizedMap<K,V>implements Map<K,V>, Serializable {private static final long serialVersionUID = 1978198479659022715L;private final Map<K,V> m;     // Backing Mapfinal Object      mutex;        // Object on which to synchronizeSynchronizedMap(Map<K,V> m) {this.m = Objects.requireNonNull(m);mutex = this;}SynchronizedMap(Map<K,V> m, Object mutex) {this.m = m;this.mutex = mutex;}public int size() {synchronized (mutex) {return m.size();}}public boolean isEmpty() {synchronized (mutex) {return m.isEmpty();}}public boolean containsKey(Object key) {synchronized (mutex) {return m.containsKey(key);}}//。。。省略很多方法

看源码,原来我们使用了该方法后,该类的类型变成了一个SynchronizedMap,并且将传入的map对象赋给了内部一个mutex对象,然后在该SynchronizedMap实现的所有方法都加上了synchronized (mutex),这个mutex不就是我们传入的原map吗?

原来如此,通过这样就实现了线程安全,其他对于List,Set的实现也和上述思路一样,不再赘述。

2.2.2 Collections的Unmodifiable操作如何实现的?

其实实现思路也和上述类似,看源码:

 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;}//省略一堆
}

我们传入的集合是一个new出来的Unmodified集合,传入的集合用了一个final关键来修饰,是不是很简单就实现了不可变集合操作!

2.2.3 你了解Collections中的search方法吗?

先看代码:

首先先定义了一堆常量,该常量和具体使用的排序方法有关,该数值是一个经验上来的一个比较优的解法。

直白点儿说就是我这个集合大小会决定我用什么算法对它进行操作。

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;

就看一个binarySearch的一个方法,该方法实现思路是二分查找,所以入参的list必须继承自Comparable接口,这样其内部有序使用二分查找会很快,当然有序是使用binarySearch方法的条件。

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
}

binarySearch()二分查找发的时候当这个List不是链表或者该链表长度小于5000的时候,使用indexedBinarySearch方法,否则使用iteratorBinarySearch方法。

2.2 Collections类 (Collections源码解析)相关推荐

  1. 【多线程】ThreadPoolExecutor类万字源码解析(注解超级详细)

    线程池 线程池初始化时是没有创建线程的,线程池里的线程的初始化与其他线程一样,但是在完成任务以后,该线程不会自行销毁,而是以挂起的状态返回到线程池.直到应用程序再次向线程池发出请求时,线程池里挂起的线 ...

  2. [Java多线程]-J.U.C.atomic包下的AtomicInteger,AtomicLong等类的源码解析

    Atomic原子类:为基本类型的封装类Boolean,Integer,Long,对象引用等提供原子操作. 一.Atomic包下的所有类如下表: 类摘要 AtomicBoolean 可以用原子方式更新的 ...

  3. 海贼跑酷 跑酷类游戏 源码解析

    源码目录,如下 引擎:cocos2.2.6 语言 c++ 这几个文件,根据名字:就可以看出来:各个scene就是场景,都是ui堆叠,不细说 主要逻辑,位于 GameScene里面: 地图使用 titl ...

  4. dubbo源码解析(十)远程通信——Exchange层

    远程通讯--Exchange层 目标:介绍Exchange层的相关设计和逻辑.介绍dubbo-remoting-api中的exchange包内的源码解析. 前言 上一篇文章我讲的是dubbo框架设计中 ...

  5. SpringBoot自动配置实现原理及源码解析(2.3.x)

    约定优于配置,这是SpringBoot中的一个很重要特性,此特性让我们可以在几秒中之内完成一个项目的搭建,无需任何配置,本文就通过深入源码的方式来探索下自动配置的实现过程 为什么要自动配置 手动配置很 ...

  6. MyBatis源码- SqlSession门面模式 selectList 源码解析

    文章目录 Pre 工程概览 pom.xml mybatis-config.xml UserMapper 测试类 selectList 源码解析 附 SQL log4j.properties app.p ...

  7. 面试必备:ArrayList源码解析(JDK8)

    概述 很久没有写博客了,准确的说17年以来写博客的频率降低到一个不忍直视的水平.这个真不怪我,给大家解释一下.  一是自从做了leader,整天各种事,开会,过需求,无限循环.心很累,时间也被无线压榨 ...

  8. Spring Cloud Gateway 源码解析(3) —— Predicate

    目录 RoutePredicateFactory GatewayPredicate AfterRoutePredicateFactory RoutePredicateHandlerMapping Fi ...

  9. JDK源码解析之Java.util.Collections

    java.util.Collections 是一个包装类.它包含有各种有关集合操作的静态多态方法.此类不能实例化,就像一个工具类,服务于Java的Collection框架. 一.源码解析 1.不可实例 ...

  10. 面试官系统精讲Java源码及大厂真题 - 04 Arrays、Collections、Objects 常用方法源码解析

    04 Arrays.Collections.Objects 常用方法源码解析 读一本好书,就是和许多高尚的人谈话. --歌德 引导语 我们在工作中都会写工具类,但如何才能使写出来的工具类更好用,也是有 ...

最新文章

  1. 正则表达式贪婪与懒惰
  2. 上海交通大学医学院附属瑞金医院首次公布预警期刊
  3. 业务专题篇:渠道流量分析
  4. 别放任这些小毛病不管!它会扩大还会造成重大危险
  5. c#string倒数第二位插入字符_【转载】C#中string类使用Substring方法截取字符串
  6. info.plist文件里面添加描述 - 配置定位,相册等
  7. 搭建MIPS平台GDB调试环境
  8. python试卷管理系统的设计与实现_《数据结构》考试系统的设计与实现.doc
  9. 加速打开win10自带图片查看器
  10. matlab求两向量夹角_MATLAB图形的标注与修饰
  11. java技术总监一般问什么_技术总监面试题(Java),看看你会多少?
  12. Python小工具:批量给视频加水印
  13. 微信可以改彩色昵称了
  14. 仙人球模型matlab,3dmax软件如何制作带刺的仙人球模型?
  15. 省心又省力的华为云等保安全服务----助力企业等保快速通过
  16. C语言编程>第二十六周 ① 函数fun的功能是:将形参b所指数组中的前半部分元素的值和后半部分元素的值对换。形参n中存放数组中数据的个数,若n为奇数,则中间的元素不动。
  17. 导航系统中的惯性技术
  18. nginx 官方文档翻译
  19. 取一个数的各个数位的数字
  20. iebook2010+绿色破解版的解压密码

热门文章

  1. 记一次Max模型导入到GIS平台歪了,尺寸不对过程分析
  2. 关于platform_device和platform_driver的匹配
  3. TensorFlow实时任意风格迁移,送女朋友的创意礼物有了
  4. Elasticsearch 未授权访问漏洞验证及修复
  5. 卷积与反卷积(转置卷积)关系的公式推导 及其各自的形式
  6. html5 银行卡号校验,JQuery验证“银行卡”卡号 代码实例
  7. Ubuntu安装autoconf
  8. Linux如何永久以命令行界面形式登录
  9. 【转载】浅谈思维教育 朱云龙
  10. I2S总线学习:I2S数据格式