集合框架JDK1.8源码分析之Collections && Arrays

Posted 张英爱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了集合框架JDK1.8源码分析之Collections && Arrays相关的知识,希望对你有一定的参考价值。

一、前言

  整个集合框架的常用类我们已经分析完成了,但是还有两个工具类我们还没有进行分析。可以说,这两个工具类对于我们操作集合时相当有用,下面进行分析。

二、Collections源码分析

  2.1 类的属性 

技术分享 View Code

  2.2 构造函数  

private Collections() {   
}    

  说明:私有构造函数,在类外无法调用。

  2.3 方法分析

  下面是Collections的所有方法。

  技术分享

  技术分享

  可以看到,Collections的方法包含了各种各样的操作。下面分析最常用的方法。

  1. sort函数

  该函数有两个重载函数,方法签名分别如下

public static <T extends Comparable<? super T>> void sort(List<T> list)
public static <T> void sort(List<T> list, Comparator<? super T> c)

  说明:对于第一个函数,参数为List<T> list,表示只能对List进行排序。由<T extends Comparable<? super T>>可知,T类型或者是T的父类型必须实现了Comparable接口。对于第二个函数,也包含了List<T> list参数,还包含了Comparator<? super T> c,表示可以指定自定义比较器Comparator。而元素类型不需要实现Comparable接口。两个函数都会调用到List类的sort方法。具体如下 

技术分享 View Code

  2. binarySearch函数

  该函数也有两个重载版本,方法签名分别如下  

public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key)
public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)

  说明:与sort函数的两个重载版本类似,可以指定自定义比较器,特别注意,使用此函数时,必须要保证List已经排好序,并且集合元素是可以比较的。其中,两个binarySearch函数会调用indexedBinarySearch函数,具体函数如下  

技术分享 View Code

  说明:该函数在List可以随机访问时被调用,效率相比iteratorBinarySearch更高,当List不能被随机访问时,将采用iteratorBinarySearch进行二分查找,即采用迭代器模式。iteratorBinarySearch具体代码如下  

技术分享 View Code

  说明:该函数会调用get函数,即遍历集合找元素,所以效率相对较低。get函数如下  

技术分享 View Code

  3. reverse函数

  此函数用于反转集合中的元素,其签名如下

public static void reverse(List<?> list)

  具体代码如下

技术分享 View Code

  说明:若集合支持随机访问或者集合大小小于反转阈值,则采用直接交换操作;否则,就会采用双迭代器模式(从头开始的,从尾开始的)进行交换。

  4. fill函数

  此函数用于给集合填充指定元素,签名如下  

public static <T> void fill(List<? super T> list, T obj)

  泛型方法,具体代码如下

技术分享 View Code

  说明:也是同reverse函数一样,分为两种情况处理。

  5. copy函数

  此函数用于拷贝集合,将源集合拷贝至目标集合,签名如下

public static <T> void copy(List<? super T> dest, List<? extends T> src)

  其具体代码如下

技术分享 View Code

  说明:也是分为两种情况进行处理,并且要确保目标集合大小大于源集合大小。

  6. min函数

  此函数用于求得集合里最小的元素,有两个重载版本,签名如下  

public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll)
public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp)

  说明:可以指定比较器,取出自定义的最小的元素。第一个函数具体代码如下

技术分享 View Code

  说明:只需要遍历一遍集合即可取出最小值,另外一个重载函数类似,不再累赘,max函数与min函数类似,不再累赘。

  7. rotate函数

  此函数用于旋转集合元素,实际就是循环右移集合里的元素,签名如下  

public static void rotate(List<?> list, int distance)

  集合元素循环右移,移动的距离为distance,具体代码如下

技术分享 View Code

  说明:也分为两种情况进行处理,分别对应rotate1、rotate2。roate1函数具体如下

技术分享 View Code

  说明:这个算法特别的巧妙,可作为面试考点。rotate2函数具体如下  

技术分享 View Code

  说明:使用递归进行旋转。

  8. replaceAll函数

  用于替换集合中所有指定元素。签名如下  

public static <T> boolean replaceAll(List<T> list, T oldVal, T newVal)

  具体代码如下

技术分享 View Code

  说明:可以替换空值null。也是分两种情况进行处理。

  9. indexOfSubList函数

  用于在指定集合索引子集合,成功,则返回位置,不成功,则返回-1。签名如下 

public static int indexOfSubList(List<?> source, List<?> target)

  具体代码如下  

技术分享 View Code

  说明:也是分为两种情况进行处理。

  10. frequency函数

  用来统计一个元素在集合中出现的次数。签名如下  

public static int frequency(Collection<?> c, Object o)

  具体代码如下 

技术分享 View Code

  说明:可以对空值null进行统计。

  11. reverseOrder函数

  反转比较逻辑,即反转集合顺序,有两个重载函数,签名如下  

public static <T> Comparator<T> reverseOrder()
public static <T> Comparator<T> reverseOrder(Comparator<T> cmp)

  函数返回类型为Comparator类型,该Comparator的比较逻辑与之前的比较逻辑相反。reverseOrder函数代码如下 

技术分享 View Code

  说明:另外一个重载函数与此类似,不再累赘。

  12. addAll函数

  用于向集合中添加多个元素,签名如下  

public static <T> boolean addAll(Collection<? super T> c, T... elements)

  说明:第二个参数为变长参数,即可以传递多个值。具体代码如下 

技术分享 View Code

  Collections的主要方法就分析到这里。下面分析Arrays类的方法。

三、Arrays源码分析

  3.1 类的属性  

技术分享 View Code

  3.2 构造函数 

private Arrays() {}

  说明:私有构造函数,类外不允许调用。

  3.3 方法分析

  Arrays的全部方法如下

  技术分享技术分享      技术分享技术分享技术分享  

  说明:可以看到,Arrays工具类处理的是数组类型。并且每个方法存在多个重载版本。

  3.4 核心方法分析

  由于存在多个重载版本,每个重载版本的逻辑大体一致,故只分析有代表性的版本。

  1. sort函数

  用于对数组进行排序,两个主要的重载版本,方法签名如下  

public static void sort(int[] a)
public static void sort(int[] a, int fromIndex, int toIndex)

  说明:第一个版本是对整个数组进行排序,第二个版本只对指定部分进行排序。第一个版本代码如下  

技术分享 View Code

  说明:使用快速排序进行排序。第二个版本与第一个版本类似,不再累赘。

  2. equals方法

  用于判断两个数组是否相等,若数组元素重写了equals方法,则按照元素的equals方法进行比较。主要的重载版本,方法签名如下  

public static boolean equals(int[] a, int[] a2)
public static boolean equals(Object[] a, Object[] a2)

  说明:第一个版本具体代码如下 

技术分享 View Code

  说明:首先,判断是否为同一个数组引用,满足后,再判断是否有数组为空,满足后,再判断两数组长度是否相等,满足后,最后遍历数组进行比较。

  3. copyOf函数

  用于复制数组元素至另一个数组。主要重载版本,签名如下  

public static <T> T[] copyOf(T[] original, int newLength)
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType)

  第二个版本,具体代码如下 

技术分享 View Code

  4. copyOfRange函数

  指定数组一段元素进行复制(指定了开始位置和结束位置),签名如下  

public static <T> T[] copyOfRange(T[] original, int from, int to)
public static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType)

  第二个版本,具体代码如下 

技术分享 View Code

  5. hashCode函数

  求得数组的hashCode,主要版本,签名如下 

public static int hashCode(int a[])

  代码如下 

技术分享 View Code

  6. asList函数

  用于将不定参数转化为List,方法签名如下  

public static <T> List<T> asList(T... a)

  具体代码如下  

技术分享 View Code 

  7. toString函数

  用于更友好的显示数组信息,签名如下 

public static String toString(int[] a)

  注意,并没有覆盖Object类的toString方法,因为方法签名不相同。具体代码如下 

技术分享 View Code

  Arrays工具类的主要方法就介绍到这里,平时我们可以多用用里面的方法,达到更熟悉的效果。

四、总结

  Collections与Arrays提供了很多有用的方法,我们平时可以多用用,至此,集合框架的主要源码就分析完了。下面会接着分析并发框架的源码,谢谢各位园友的观看~

  

  

 

  

  

以上是关于集合框架JDK1.8源码分析之Collections && Arrays的主要内容,如果未能解决你的问题,请参考以下文章

集合之HashSet(含JDK1.8源码分析)

集合之LinkedHashSet(含JDK1.8源码分析)

集合之LinkedList(含JDK1.8源码分析)

集合之TreeSet(含JDK1.8源码分析)

ArrayList集合(JDK1.8)

根据jdk1.8源码整理而得,java集合体系(继承实现关系)图解,超清晰,一看就懂,方便记忆