哈喽,大家好,我是指北君。 日常开发中,我们会使用各种工具类,利用封装好的轮子,能让我们的开发事半功倍。但是在JDK中,有一个特别的工具类——java.lang.Arrays.class,其源码实现还是挺精湛,接下来让我们来揭开它神秘的面纱。
java.util.Arrays 类是 JDK 提供的一个工具类,用来处理数组的各种方法,而且每个方法基本上都是静态方法,能直接通过类名Arrays调用。
1、asList
1 |
|
作用是返回由指定数组支持的固定大小列表。
注意:这个方法返回的 ArrayList 不是我们常用的集合类 java.util.ArrayList。这里的 ArrayList 是 Arrays 的一个内部类 java.util.Arrays.ArrayList。这个内部类有如下属性和方法:
1 |
|
①、返回的 ArrayList 数组是一个定长列表,我们只能对其进行查看或者修改,但是不能进行添加或者删除操作
通过源码我们发现该类是没有add()或者remove() 这样的方法的,如果对其进行增加或者删除操作,都会调用其父类 AbstractList 对应的方法,而追溯父类的方法最终会抛出 UnsupportedOperationException 异常。如下:
1 |
|
②、引用类型的数组和基本类型的数组区别
1 |
|
上面的结果第一个listStr.size()==3,而第二个 listI.size()==1。这是为什么呢?
我们看源码,在 Arrays.asList 中,方法声明为
所以将上面的方法泛型化补全应该是:
1 |
|
③、返回的列表ArrayList里面的元素都是引用,不是独立出来的对象
1 |
|
这里的Arrays.toString()方法就是打印数组的内容,后面会介绍。我们看修改集合的内容,原数组的内容也变化了,所以这里传入的是引用类型。
④、已知数组数据,如何快速获取一个可进行增删改查的列表List?
1 |
|
这里的ArrayList 集合类后面我们会详细讲解,大家目前只需要知道有这种用法即可。
⑤、Arrays.asList() 方法使用场景
Arrays工具类提供了一个方法asList, 使用该方法可以将一个变长参数或者数组转换成List 。但是,生成的List的长度是固定的;能够进行修改操作(比如,修改某个位置的元素);不能执行影响长度的操作(如add、remove等操作),否则会抛出UnsupportedOperationException异常。
所以 Arrays.asList 比较适合那些已经有数组数据或者一些元素,而需要快速构建一个List,只用于读取操作,而不进行添加或删除操作的场景。
2、sort
该方法是用于数组排序,在 Arrays 类中有该方法的一系列重载方法,能对7种基本数据类型,包括 byte,char,double,float,int,long,short 等都能进行排序,还有 Object 类型(实现了Comparable接口),以及比较器 Comparator 。
①、基本类型的数组
这里我们以 int[ ] 为例看看:
1 |
|
通过调用 sort(int[] a) 方法,将原数组按照升序的顺序排列。下面我们通过源码看看是如何实现排序的:
1 |
|
在 Arrays.sort 方法内部调用 DualPivotQuicksort.sort 方法,这个方法的源码很长,分别对于数组的长度进行了各种算法的划分,包括快速排序,插入排序,冒泡排序都有使用。详细源码可以参考这篇博客。
②、对象类型数组
该类型的数组进行排序可以实现 Comparable 接口,重写 compareTo 方法进行排序。
1 |
|
String 类型实现了 Comparable 接口,内部的 compareTo 方法是按照字典码进行比较的。
③、没有实现Comparable接口的,可以通过Comparator实现排序
1 |
|
3、binarySearch
用二分法查找数组中的某个元素。该方法和 sort 方法一样,适用于各种基本数据类型以及对象。
注意:二分法是对以及有序的数组进行查找(比如先用Arrays.sort()进行排序,然后调用此方法进行查找)。找到元素返回下标,没有则返回 -1
实例:
1 |
|
具体源码实现:
1 |
|
4、copyOf
拷贝数组元素。底层采用 System.arraycopy() 实现,这是一个native方法。
1 |
|
src:源数组
srcPos:源数组要复制的起始位置
dest:目的数组
destPos:目的数组放置的起始位置
length:复制的长度
注意:src 和 dest都必须是同类型或者可以进行转换类型的数组。
1 |
|
1 |
|
5、fill
该系列方法用于给数组赋值,并能指定某个范围赋值。
1 |
|
6、toString 和 deepToString
toString 用来打印一维数组的元素,而 deepToString 用来打印多层次嵌套的数组元素。
1 |
|
7、小结
好了,这就是JDK中java.lang.Arrays 类的源码解析。
指北君后续的文章会给大家介绍JDK的各种源码,让大家吃透JDK,另外还有各种工作趣闻,面试宝典。
我是指北君,操千曲而后晓声,观千剑而后识器。感谢各位人才的:点赞、收藏和评论,我们下期更精彩!