目录
java.util.Arrays类是一个操作数组的工具类,包含各种操作数组的方法,允许将数组视为列表
一.数组和列表的区别
1.数组(Array)
(1)数组(Array)
Java语言中提供的数组是用来存储固定大小的同类型元素。
- 数组是数据结构中的一种线性数据结构。
- 数组可以说是一个容器或者是一个集合。
- 在数组中只能存储同一类型的数据,在定义数组的时候必须要指定数据类型。
- 如果数组中要添加不同的数据类型,只需把数组的类型定义为Object。
- 数组能存储的元素个数是固定的,因为数组在定义的时候必须要指定长度。
- Java中数组是类,它只有唯一一个属性length(数组的长度)。
- length属性的计算值是从1开始计算的,而数组的下标,是从0开始计算的。
(2)数组的声明与创建
首先必须声明数组变量,才能在程序中使用数组。
dataType[] arrayRefVar; (首选) 或 dataType arrayRefVar[];
Java使用new操作符来创建数组。
arrayRefVar = new dataType[arraySize];
我们也可以将声明和创建用一条语句完成:
dataType[] arrayRefVar = new dataType[arraySize];
我们也可以这样来创建数组:
dataType[] arrayRefVar = {value0,value1,value2,value3,value4,value5};
(3)多维数组
Java 中没有多维数组的概念,从数组底层的运行机制上来看 Java 没有多维数组,但是 Java 提供了支持多维数组的语法,可以实现多维数组的功能。
Java 语言里的数组类型是引用类型,因此数组变量其实是一个引用,这个引用指向真实的数组内存。数组元素的类型也可以是引用,如果数组元素的引用再次指向真实的数组内存,这种情形看上去很像多维数组。
所以, 多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。
多维数组的动态初始化(以二维为例)
type[][] typeName = new type[typeLength1][typeLength2]; (首选)
type[] typeName[] = new type[typeLength1][typeLength2];
type typeName[][] = new type[typeLength1][typeLength2];
(typeLength1是行数,typeLength2是列数 )
由于多维数组可以看成是数组的数组,我们同样可以分别为每一维分配引用空间
String[][] str = new String;
str[0] = new String[2]; //该二维数组有2行
str[1] = new String[2]; //该二维数组有2列
多维数组的引用 (以二维为例)
对二维数组中的每个元素,引用方式为arrayName[index1][index2],index1为行索引,index2为列索引
str[1][0]; //第二行第一列
(4)数组的优缺点
优点:数组是所有数据结构中存储和获取速度最快的一种。
缺点:数组的长度是固定的,如果要删除或添加数据会不方便,删除的时候空间会浪费,添加的时候如果数据已经加满了,就无法添加新的数据。
2.列表(ArrayList)
本文的列表主要用于和数组做对比,ArrayList的实现基于数组,LinkedList的实现基于双向链表,故本文主要介绍ArrayList
(1)列表(ArrayList)
ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
(2)列表的声明与创建
ArrayList 类位于 java.util 包中,使用前需要引入它
import java.util.ArrayList;
ArrayList<E> objectName = new ArrayList<>();
//E:泛型数据类型,只能为引用数据类型
(3)列表的优缺点
优点:
- 支持自动改变大小
- 可以灵活的插入元素
- 可以灵活的删除元素
缺点:牺牲效率,比一般的数组慢
3.数组(Array)与列表(ArrayList)的区别
列表(ArrayList)是对数组(Array)的一个加强
(1)空间大小
- Array的空间大小是固定的,空间不够时也不能再次申请,所以需要事前确定合适的空间大小。
- ArrayList的空间是动态增长的,如果空间不够,它会创建一个空间比原空间大0.5倍的新数组,然后将所有元素复制到新数组中,接着抛弃旧数组。而且,每次添加新的元素的时候都会检查内部数组的空间是否足够。
(2)存储内容
- Array数组可以包含基本类型和对象类型。
- ArrayList却只能包含对象类型。
(3)删除方法
- Array数组没有提供删除方法
- ArrayList中有remove()方法
建议:基于效率和类型检验,应尽可能使用Array, 无法确定数组大小时使用ArrayList,
解决一般化的问题时,建议使用ArrayList。
二.Arrays类常用方法
Arrays类里的方法均被static修饰(即为静态方法),故可以直接通过Arrays.xxx(xxx)的形式调用方法,下面介绍Arrays类的一些常用方法,常用方法大致可以分为:赋值,排序,查找,比较,复制
1.赋值
fill()
将指定的值分配给指定数组指定范围中的每个元素。
public static void fill(arrayname,value)
或
public static void fill(arrayname ,starting index ,ending index ,value)
import java.util.*;
public class Example{
public static void main(String[] args) {
int array[] = new int[10];
Arrays.fill(array, 1);
for (int arrays:array) {
System.out.print(arrays+" ");
}
System.out.println();
Arrays.fill(array, 3, 6, 9);
for (int arrays:array) {
System.out.print(arrays+" ");
}
}
}
1 1 1 1 1 1 1 1 1 1
1 1 1 9 9 9 1 1 1 1
2.排序
sort()
对指定对象数组根据其元素的自然顺序进行升序排列。
public static void sort(Object[] arrayname)
//对一个数组的所有元素进行排序,并且是按从小到大的顺序
public static void sort(Object[] arrayname,int fromIndex, int toIndex)
//对数组部分排序,也就是对数组a的下标从fromIndex到toIndex-1的元素排序
import java.util.*;
public class Example{
public static void main(String[] args) {
int array[] = {2,5,85,30,75,66,-18,0};
Arrays.sort(array,2,5);
for (int arrays:array) {
System.out.print(arrays+" ");
}
System.out.println();
Arrays.sort(array);
for (int arrays:array) {
System.out.print(arrays+" ");
}
}
}
2 5 30 75 85 66 -18 0
-18 0 2 5 30 66 75 85
Arrays.sort()的底层原理:
假设数组长度为n
- 1<=n<47,使用插入排序
- 47<=n<286,使用快速排序
- n>=286,使用归并排序或快速排序(有一定顺序使用归并排序,毫无顺序使用快速排序)
这里简单了解即可,关于各种排序的算法原理和复现,后续在讲算法的时候会单独发一篇博客来说明的
3.查找
binarySearch()
用二分查找算法在给定数组中搜索给定值的对象。
数组在调用前必须排序好的。
public static int binarySearch(Object[] a,Object key)
//在一个数组的所有元素中进行查找
返回值:
- 在数组范围内,索引值为“ - 插入点索引值”
- 小于数组内元素,索引值为 – 1
- 大于数组内元素,索引值为 – (length + 1)
public static int binarySearch(Object[] a,int fromIndex,int toIndex,Object key)
//在该数组指定的范围内进行查找
返回值:
- 在搜索范围内,索引值为“ - 插入点索引值”
- 小于搜索范围内元素,返回–(fromIndex + 1)
- 大于搜索范围内元素,返回 –(toIndex + 1)
import java.util.*;
public class Example{
public static void main(String[] args) {
int array[] = {2,5,85,30,75,66,-18,0};
Arrays.sort(array);
for (int arrays:array) {
System.out.print(arrays+" ");
}
System.out.println();
System.out.println(Arrays.binarySearch(array,5));
System.out.println(Arrays.binarySearch(array,-99));
System.out.println(Arrays.binarySearch(array,100));
System.out.println(Arrays.binarySearch(array,60));
System.out.println(Arrays.binarySearch(array,1,5,5));
System.out.println(Arrays.binarySearch(array,1,5,-99));
System.out.println(Arrays.binarySearch(array,1,5,100));
System.out.println(Arrays.binarySearch(array,1,5,60));
}
}
-18 0 2 5 30 66 75 85
3 //5在数组内,返回排完序后的索引3
-1 //-99小于数组内元素,返回索引值为-1
-9 //100大于数组内元素,返回索引值为-(length+1)=-(8+1)
-6 //60在数组范围内,返回索引值为-插入点索引值=-6
3 //5在搜索范围内,返回排完序后的索引3
-2 //-99小于搜索范围内元素,返回–(fromIndex + 1)=-(1+1)=-2
-6 //100大于搜索范围内元素,返回–(toIndex + 1)=-(5+1)=-6
-6 //60在搜索范围内,索引值为-插入点索引值=-6
二分查找算法原理和复现也会在之后的博客里提到
4.比较
equals()
如果两个指定的数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的,则认为这两个数组是相等的。换句话说,如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。
public static boolean equals(Object[] arrayname,Object[] arrayname2)
import java.util.*;
public class Example{
public static void main(String[] args) {
int[] array1 = {2,5,85,30,75,66,-18,0};
int[] array2 = {75,2,66,30,5,85,0,-18};
if(Arrays.equals(array1, array2)){
System.out.println("array1等于array2");
}
else{
System.out.println("array1不等于array2");
}
Arrays.sort(array1);
Arrays.sort(array2);
for(int arrays:array1){
System.out.print(arrays+" ");
}
System.out.println();
for(int arrays:array2){
System.out.print(arrays+" ");
}
System.out.println();
if(Arrays.equals(array1, array2)){
System.out.println("排序后,array1等于array2");
}
else{
System.out.println("排序后,array1不等于array2");
}
}
}
array1不等于array2
-18 0 2 5 30 66 75 85
-18 0 2 5 30 66 75 85
排序后,array1等于array2
5.复制
copyOf()
将原始数组的元素,复制到新的数组中,可以设置复制的长度(即需要被复制的元素个数)
public static Object[] copyOf(original,newLength)
copyOfRange()
将某个范围内的元素复制到新的数组中
public static Object[] copyOfRange(original,int from,int to)
//from为拷贝的开始位置(包含),to为拷贝的结束位置(不包含)
import java.util.*;
public class Example{
public static void main(String[] args) {
int[] array1 = {2,5,85,30,75,66,-18,0};
int[] array2 = Arrays.copyOf(array1, 6);
int[] array3 = Arrays.copyOfRange(array1, 2, 4);
System.out.println(Arrays.toString(array1));
System.out.println(Arrays.toString(array2));
System.out.println(Arrays.toString(array3));
}
}
[2, 5, 85, 30, 75, 66, -18, 0]
[2, 5, 85, 30, 75, 66]
[85, 30]