源码(09) -- java.util.Arrays
java.util.Arrays 源码分析
---------------------------------------------------------------------------------
java.util.Arrays是一个工具类,它的定义如下:
public class Arrays {
//Sorting of primitive type arrays. // Searching // Equality Testing // Filling // Cloning //hashCode //toString
}
从上面的定义可以看出java.util.Arrays这个类包含用来操作数组的各种方法。
------------------------------------------------------------------------------------
下面来看看java.util.Arrays中具体有哪些方法:
copyOf(T[] original,int newLength) | 复制指定的数组 |
copyOfRange(T[] original,int from,int to) | 将指定数组的指定范围复制到一个新数组 |
binarySearch(Object[] a,Object key) | 使用二分搜索法来搜索指定数组,以获得指定对象 |
deepEquals(Object[] a1,Object[] a2) | 如果两个指定数组彼此是深层相等的,则返回true |
deepHashCode(Object[] a) | 基于指定数组的"深层内容"返回哈希值 |
deepToString(Object[] a) | 返回指定数组"深层内容"的字符串表示形式 |
equals(Object[] a,Object[] a2) | 如果两个指定的Object数组相等,则返回true |
fill(Object[] a,Object val) | 将指定的Object引用分配给指定Object数组的每个元素 |
hashCode(Object[] a) | 基于指定数组的内容返回哈希码 |
sort(Object[] a) | 根据元素的自然顺序对指定对象数组按升序进行排序 |
toString(Object[] a) | 返回指定数组内容的字符串表示形式 |
asList(T ... a) | 返回一个受指定数组支持的固定大小的列表 |
------------------------------------------------------------------------------------
java.util.Arrays中的copy方法:
//复制指定的数组(针对boolean类型)
public static boolean[] copyOf(boolean[] original,int newLength) //复制指定的数组(针对byte类型)
public static byte[] copyOf(byte[] original,int newLength) //复制指定的数组(针对char类型)
public static char[] copyOf(char[] original, int newLength) //复制指定的数组(针对double类型)
public static double[] copyOf(double[] original, int newLength) //复制指定的数组(针对float类型)
public static float[] copyOf(float[] original, int newLength) //复制指定的数组(针对int类型)
public static int[] copyOf(int[] original, int newLength) //复制指定的数组(针对long类型)
public static long[] copyOf(long[] original,int newLength) //复制指定的数组(针对short类型)
public static short[] copyOf(short[] original,int newLength) //复制指定的数组(针对T类型)
public static <T> T[] copyOf(T[] original, int newLength) //复制指定的数组(针对T类型)
public static <T,U> T[] copyOf(U[] original, int newLength,Class<? extends T[]> newType)
在对copy方法进行详细介绍之前,必须先来看看java.lang.System类中的arraycopy方法,因为java.util.Arrays类中的copy方法都是基于java.lang.System类的arraycopy方法实现的。
/*
从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。从 src 引用的源数组到 dest 引用的目标数组,数组组件的一个子序列被复制下来。被复制的组件的编号等于 length 参数。源数组中位置在 srcPos 到 srcPos+length-1 之间的组件被分别复制到目标数组中的 destPos 到 destPos+length-1 位置。
如果参数 src 和 dest 引用相同的数组对象,则复制的执行过程就好像首先将 srcPos 到 srcPos+length-1 位置的组件复制到一个带有 length 组件的临时数组,然后再将此临时数组的内容复制到目标数组的 destPos 到 destPos+length-1 位置一样。 如果 dest 为 null,则抛出 NullPointerException 异常。
如果 src 为 null, 则抛出 NullPointerException 异常,并且不会修改目标数组。
否则,只要下列任何情况为真,则抛出 ArrayStoreException 异常并且不会修改目标数组:
src 参数指的是非数组对象。
dest 参数指的是非数组对象。
src 参数和 dest 参数指的是那些其组件类型为不同基本类型的数组。
src 参数指的是具有基本组件类型的数组且 dest 参数指的是具有引用组件类型的数组。
src 参数指的是具有引用组件类型的数组且 dest 参数指的是具有基本组件类型的数组。
否则,只要下列任何情况为真,则抛出 IndexOutOfBoundsException 异常,并且不会修改目标数组:
srcPos 参数为负。
destPos 参数为负。
length 参数为负。
srcPos+length 大于 src.length,即源数组的长度。
destPos+length 大于 dest.length,即目标数组的长度。
否则,如果源数组中 srcPos 到 srcPos+length-1 位置上的实际组件通过分配转换并不能转换成目标数组的组件类型,则抛出 ArrayStoreException 异常。在这种情况下,将 k 设置为比长度小的最小非负整数,这样就无法将 src[srcPos+k] 转换为目标数组的组件类型;当抛出异常时,从 srcPos 到 srcPos+k-1 位置上的源数组组件已经被复制到目标数组中的 destPos 到 destPos+k-1 位置,而目标数组中的其他位置不会被修改。
*/
public static native void arraycopy(Object src,int srcPos,Object dest,int destPos,int length);
下面以基本类型int来举例说明:
源代码如下:
public static int[] copyOf(int[] original, int newLength) {
//创建一个长度为newLength的int类型数组
int[] copy = new int[newLength]; //复制指定的数组
System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
return copy;
}
示例代码:
public class ArraysTest { public static void main(String[] args) {
//源数组
int[] original = {7,5,1,9,14,11,19,33,21}; //通过java.util.Arrays类的copyOf方法对源数组进行复制
int[] dest = Arrays.copyOf(original, 4);
for(int i = 0;i < dest.length;i++){
System.out.print(dest[i] + " ");
}
System.out.println();
System.out.println("---------------------");
//通过java.util.Arrays类的copyOf方法对源数组进行复制(如果复制的长度超过了源数组的长度,则用0填充)
int[] dest1 = Arrays.copyOf(original, 20);
for(int i = 0;i < dest1.length;i++){
System.out.print(dest1[i] + " ");
}
}
} 运行结果:
7 5 1 9
---------------------
7 5 1 9 14 11 19 33 21 0 0 0 0 0 0 0 0 0 0 0
接下来看看基本类型: byte、short、long、char、float、double、boolean的copyOf方法
源代码如下:
public static byte[] copyOf(byte[] original, int newLength) {
//创建一个长度为newLength的的byte数组
byte[] copy = new byte[newLength];
//复制数组
System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
return copy;
} public static short[] copyOf(short[] original, int newLength) {
//创建一个长度为newLength的的short数组
short[] copy = new short[newLength];
//复制数组
System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
return copy;
} public static long[] copyOf(long[] original, int newLength) {
//创建一个长度为newLength的的long数组
long[] copy = new long[newLength];
//复制数组
System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
return copy;
} public static char[] copyOf(char[] original, int newLength) {
//创建一个长度为newLength的的char数组
char[] copy = new char[newLength];
//复制数组
System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
return copy;
} public static float[] copyOf(float[] original, int newLength) {
//创建一个长度为newLength的的float数组
float[] copy = new float[newLength];
//复制数组
System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
return copy;
} public static double[] copyOf(double[] original, int newLength) {
//创建一个长度为newLength的的double数组
double[] copy = new double[newLength];
//复制数组
System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
return copy;
} public static boolean[] copyOf(boolean[] original, int newLength) {
//创建一个长度为newLength的的boolean数组
boolean[] copy = new boolean[newLength];
//复制数组
System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
return copy;
}
接下来看看:
//复制指定的数组(针对T类型)
public static <T> T[] copyOf(T[] original, int newLength) //复制指定的数组(针对T类型)
public static <T,U> T[] copyOf(U[] original, int newLength,Class<? extends T[]> newType)
源代码如下:
public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
} public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
//创建一个长度为newLength的T类型的数组
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength); //复制数组
System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
return copy;
}
示例代码:
public class Student {
private String name;
private int age; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
} /**
* 初始化数据,测试时用
* @return
*/
public static Student[] initData(){
Student[] stus = new Student[10];
for(int i = 0;i < 10;i++){
Student stu = new Student();
stu.setName("同学"+i);
stu.setAge(i);
stus[i] = stu;
}
return stus;
}
} import java.util.Arrays; public class ArraysTest {
public static void main(String[] args) {
//源数组
Student[] stus = Student.initData();
System.out.print("源数组Student[]内容为: ");
for(int i = 0;i < stus.length;i++){
System.out.print(stus[i] + " ");
}
System.out.println();
//通过java.util.Arrays类的copyOf方法对源数组进行复制
Student[] dest = Arrays.copyOf(stus, 6);
System.out.print("复制长度为6的子数组: ");
for(int i = 0;i < dest.length;i++){
System.out.print(dest[i] + " ");
}
System.out.println();
//通过java.util.Arrays类的copyOf方法对源数组进行复制(如果复制的长度超过了源数组的长度,则用0填充)
Student[] dest1 = Arrays.copyOf(stus, 20);
System.out.print("复制长度为20的子数组: ");
for(int i = 0;i < dest1.length;i++){
System.out.print(dest1[i] + " ");
}
System.out.println();
}
} 运行结果:
源数组Student[]内容为: Student [name=同学0, age=0] Student [name=同学1, age=1] Student [name=同学2, age=2] Student [name=同学3, age=3] Student [name=同学4, age=4] Student [name=同学5, age=5] Student [name=同学6, age=6] Student [name=同学7, age=7] Student [name=同学8, age=8] Student [name=同学9, age=9]
复制长度为6的子数组: Student [name=同学0, age=0] Student [name=同学1, age=1] Student [name=同学2, age=2] Student [name=同学3, age=3] Student [name=同学4, age=4] Student [name=同学5, age=5]
复制长度为20的子数组: Student [name=同学0, age=0] Student [name=同学1, age=1] Student [name=同学2, age=2] Student [name=同学3, age=3] Student [name=同学4, age=4] Student [name=同学5, age=5] Student [name=同学6, age=6] Student [name=同学7, age=7] Student [name=同学8, age=8] Student [name=同学9, age=9] null null null null null null null null null null
从前面的源代码和示例代码可以看出,java.util.Arrays中的10个copyOf(src,length)方法的作用就是对源数组进行复制,复制的长度为length.
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
源码(09) -- java.util.Arrays的更多相关文章
- JDK1.8源码(四)——java.util.Arrays 类
java.util.Arrays 类是 JDK 提供的一个工具类,用来处理数组的各种方法,而且每个方法基本上都是静态方法,能直接通过类名Arrays调用. 1.asList public static ...
- JDK1.8源码(四)——java.util.Arrays类
一.概述 1.介绍 Arrays 类是 JDK1.2 提供的一个工具类,提供处理数组的各种方法,基本上都是静态方法,能直接通过类名Arrays调用. 二.类源码 1.asList()方法 将一个泛型数 ...
- 源码(03) -- java.util.Collection<E>
java.util.Collection<E> 源码分析(JDK1.7) -------------------------------------------------------- ...
- JDK1.8源码(五)——java.util.Vector类
JDK1.8源码(五)--java.lang. https://www.cnblogs.com/IT-CPC/p/10897559.html
- 源码(05) -- java.util.AbstractCollection<E>
java.util.AbstractCollection<E> 源码分析(JDK1.7) ------------------------------------------------- ...
- JDK1.8源码(五)——java.util.ArrayList 类
关于 JDK 的集合类的整体介绍可以看这张图,本篇博客我们不系统的介绍整个集合的构造,重点是介绍 ArrayList 类是如何实现的. 1.ArrayList 定义 ArrayList 是一个用数组实 ...
- Java源码之 java.util.concurrent 学习笔记01
准备花点时间看看 java.util.concurrent这个包的源代码,来提高自己对Java的认识,努力~~~ 参阅了@梧留柒的博客!边看源码,边通过前辈的博客学习! 包下的代码结构分类: 1.ja ...
- 源码(04) -- java.util.List<E>
java.util.List<E> 源码分析(JDK1.7) --------------------------------------------------------------- ...
- 源码(06) -- java.util.AbstractList<E>
java.util.AbstractList<E> 源码分析(JDK1.7) ------------------------------------------------------- ...
随机推荐
- nginx做反向负载均衡,后端服务器获取真实客户端ip
首先,在前端nginx上需要做如下配置: location / proxy_set_header host $host; proxy_set_header X-fo ...
- (简单) POJ 2251 Dungeon Master,BFS。
Description You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is co ...
- protobuf c++ API
1.在.proto文件中定义消息格式 2.使用protobuf编译器 3.使用c++ api来读写消息 0.为何使用protobuf? 1.原始内存数据结构,可以以二进制方式sent/save ...
- C++异常(exception)第一篇--综合讲解
摘要:catch(exception &ex)是捕获所有标准库定义中的类std:exception;catch(...)则是捕获所有的异常. 1.简介 异常是由语言提供的运行时刻错误处理的一种 ...
- input的onchange事件实际触发条件与解决方法
input中onchange事件已经属于元老级别了,并且现在同onclick一样使用频率很高,然而onchange的机制实际上有很多童鞋并不清楚,我们通过实例来分析这个事件的特征. 触发onchang ...
- ucos信号量集源码分析
在实际的应用之中,一个任务经常需要等待多个信号量的同时生效,或者说任务需要根据多个信号量的组合作用的结果来决定任务的运行方式,为了实现这种多信号量组合的功能,ucos实现了信号量集的特殊结构. 信号量 ...
- Xcode6之后创建Pch预编译文件
在Xcode6之前,创建一个新工程xcode会在Supporting files文件夹下面自动创建一个“工程名-Prefix.pch”文件,也是一个头文件,pch头文件的内容能被项目中的其他所有源文件 ...
- 【转】VS2013动态库文件的创建及其使用详解
一.VS2013动态库文件的创建 1.新建项目,win32,win32项目,输入项目名称,例如MakeDll. 2.”确定“——”下一步“,选择”DLL“选项,再点”完成“: 3.菜单栏选择”项目“— ...
- 【转】安卓布局:layout_weight的理解
android:layout_weight详细分析介绍: 布局文件是:<?xml version="1.0" encoding="utf-8"?>& ...
- CSS中怎么让DIV居中
CSS 如何使DIV层水平居中 今天用CSS碰到个很棘手的问题,DIV本身没有定义自己居中的属性, 网上很多的方法都是介绍用上级的text-align: center然后嵌套一层DIV来解决问题. 可 ...