目录
1. 数组的基本用法
1.1 数组的创建
//1
int[] arr1 = {1,2,3,4,5}; //[]中不能含有数字
//创建长度为5的arr1数组并初始化其5个元素依次为12345
//2
int[] arr2 = new int[3]; //创建数组arr2,长度为3,元素均为0;
//3
int[] arr3 = new int[]{1,2,3,4,5};
//创建长度为5的arr3数组并初始化其5个元素依次为12345
//1与3的创建结果相同
//4 不建议下述写法:
int arr4[] = {1,2,3,4,5};
1.2 数组的使用
1.2.1 获取元素与访问元素
public static void main(String[] args) {
int[]arr1 = {1,2,3,4,5,6};
System.out.println("The length of the array is "+arr1.length);
System.out.println("The element with index[4] is "+arr1[4]);
arr1[4]=50;
System.out.println("The element with index[4] now is "+arr1[4]);
}
输出结果为:
注:Java的数组访问下标不可以是负数:
试运行:
int[]arr1 = {1,2,3,4,5,6};
System.out.println("The element with index [-1] is "+arr1[-1]);
报错如下:
1.2.2 遍历数组
int[] arr1={1,2,3,4,5,6};
//方法一:for循环遍历数组
for(int i=0;i<arr1.length;i++){
System.out.print(arr1[i]+" ");
}
System.out.println();
//方法二:for-each(增强for循环)遍历数组
for(int x:arr1){
System.out.print(x+" ");
}
System.out.println();
//方法三:借助java操作数组的工具类Arrays:将参数的数组以字符串形式输出
String str = Arrays.toString(arr1);
System.out.println(str);
输出结果为:
注:for循环与for-each循环的区别在于,for循环是可以得到下标的,for-each是得不到下标的;
for-each会更多地使用到集合中;
2.数组作为方法的参数
2.1 JVM内存分布
注:引用不一定存储在栈上,一个变量存储的位置取决于其性质。
局部变量就会存储在栈上,实例成员变量不一定在栈上。
2.2 基本用法
代码示例1:
运行代码如下:
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6};
print(array);
}
public static void print(int[] array){
for(int i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
System.out.println();
}
输出结果如下:
逻辑如下:
代码示例2:
运行代码如下:
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6};
System.out.println(Arrays.toString(array));
func1(array);
System.out.println(Arrays.toString(array));
func2(array);
System.out.println(Arrays.toString(array));
}
public static void func1(int[] array){
array = new int[] {11,2,13,4,51,61};
}
public static void func2(int[] array){
array[0]=899;
}
输出结果为:
fun1函数的调用执行逻辑如下:
2.3 空引用null
(1)常见引用使用含义:
int[] array1={1,2,3,4,5};
int[] array2=array1;
//array2这个引用也指向了array1这个引用指向的对象
int[] array3=null;
//array3这个引用不指向任何对象
int[] array4 = new int[]{5,6,7,8,9};
array4 = new int[10];
//一个引用不能同时指向多个对象,一个引用只能保存一个对象的地址
//array4最终只保存了new int[10]的地址
(2)引用是指向对象的、存储对象地址的变量,故而当:
int[] arr2 = null; //代表引用arr2不指向任何对象
System.out.println(arr2.length);
时,会报错如下:
(3)应用示例:使用数组交换两个变量的值:
public static void main(String[] args) {
//使用方法交换两个变量的值
int a=10;
int b=20;
int[] array={10,20};
System.out.println("Before Swap:a="+array[0]+",b="+array[1]);
Swap(array);
System.out.println("Before Swap:a="+array[0]+",b="+array[1]);
}
public static void Swap(int[] arr){
int tmp=arr[0];
arr[0]=arr[1];
arr[1]=tmp;
}
输出结果如下:
3. 数组作为方法的返回值
代码示例:使用方法将数组的每个元素都*2:
public static void main(String[] args) {
//使用方法将数组的每个元素都*2
int[] array={1,2,3,4,5};
System.out.println("Original array:"+Arrays.toString(array));
MulDouble1(array);
System.out.println("Function MulDouble1:"+Arrays.toString(array));
//创建引用变量接收以数组为返回值的方法的返回值
int[] ret = MulDouble2(array);
System.out.println("Function MulDouble2:"+Arrays.toString(ret));
}
//使用数组作为方法返回值
public static int[] MulDouble2(int[] arr){
int[] ret=new int[arr.length];
for(int i=0;i<arr.length;i++){
ret[i]=arr[i]*2;
}
return ret;
}
public static void MulDouble1(int[] arr){
for(int i=0;i<arr.length;i++){
arr[i] = arr[i]*2;
}
}
输出结果为:
注:上述代码的MulDouble1 函数虽然实现了将数组每个元素都*2功能,但也改变了元素组的内容,而MulDouble2 方法并没有改变数组的内容;
4. 数组练习
4.1 编写方法将数组以字符串形式输出
public static void main(String[] args) {
int[] array={1,2,3,4,5};
System.out.println(my_toString(array));
}
public static String my_toString(int[] arr){
if(arr==null){
return null;
}
String str="[";
for(int i=0;i<arr.length;i++){
str+=arr[i];
if(i!=arr.length-1){
str+=",";
}
}
str+="]";
return str;
}
输出结果为:
4.2 找数组中的最大元素
public static void main(String[] args) {
int[] array={12,8,1,2,10};
System.out.println("The max element is "+maxElm(array));
}
public static int maxElm(int[] arr){
if(arr==null){
return -1;
}
if(arr.length==0){
return 0;
}
int max=arr[0];
for(int i=0;i<arr.length;i++){
if(max<arr[i]){
max=arr[i];
}
}
return max;
}
输出结果为:
4.3 求数组中元素的平均值
public static void main(String[] args) {
int[] array={1,2,3,4,5,6};
System.out.println("The average num is "+ ave(array));
}
public static double ave(int[] arr){
int sum=0;
for(int x:arr){
sum+=x;
}
double ave =(double) sum/arr.length;
return ave;
}
输出结果为:
4.4 数组指定元素的查找
(1)无序数组的顺序查找:
public static void main(String[] args) {
int[] array={1,9,4,2,15,1};
Scanner scanner = new Scanner(System.in);
int key = scanner.nextInt();
System.out.println("The index of element "+key+" is "+elmFind(array,key));
}
public static int elmFind(int[] arr,int key ){
for(int i=0;i<arr.length;i++){
if(arr[i]==key){
return i;
}
}
return -1; //数组的下标不可能为负数,返回-1即表示查找失败
}
输出结果为:
(2)有序数组的二分查找:
public static void main(String[] args) {
int[] array={1,2,3,4,5,6};
Scanner scanner = new Scanner(System.in);
int key = scanner.nextInt();
System.out.println("The index of element "+key+" is "+elmFind(array,key));
}
public static int binarySearch(int[] arr,int key){
int left=0,right=arr.length-1;
while(left<=right) {
int mid = (left + right) / 2;
if (key < arr[mid]) {
right = mid - 1;
} else if (key > arr[mid]) {
left = mid + 1;
}
else{
return mid;
}
}
return -1;
}
输出结果为:
注:操作数组工具Arrays中其实已经实现了二分查找方法,可以进行直接调用:
运行下文代码:
public static void main(String[] args) {
int[] array={1,2,3,4,5,6};
Scanner scanner = new Scanner(System.in);
int key = scanner.nextInt();
System.out.println("The index of element "+key+" is "+Arrays.binarySearch(array,key));
}
输出结果为:
4.5 检查数组的有序性
public static void main(String[] args) {
//检查数组的有序性(升序为例)
int[] array1 ={12,13,14,15,16};
int[] array2 ={12,15,17,16,13};
System.out.println("array1 is sorted ?"+isSorted(array1));
System.out.println("array2 is sorted ?"+isSorted(array2));
}
public static boolean isSorted(int[] arr){
for(int i=0;i<arr.length-1;i++){
if(arr[i]>arr[i+1]){
return false;
}
}
return true;
}
输出结果为:
4.6 数组排序(冒泡排序)
public static void main(String[] args) {
int[] array={11,2,3,14,15};
bubbleSort(array);
System.out.println(Arrays.toString(array));
}
public static void bubbleSort(int[] arr){
for(int i=0;i<arr.length-1;i++){
boolean flag = false;
for(int j=0;j<arr.length-1-i;j++){
if(arr[j]>arr[j+1]){
int tmp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=tmp;
flag=true;
}
}
if(flag==false){
break;
}
}
}
输出结果为:
4.7 数组逆序
public static void main(String[] args) {
//数组逆序
int[] array={1,2,3,4,5};
reverse(array);
System.out.println(Arrays.toString(array));
String str = reverse2(array);
System.out.println(str);
}
public static void reverse(int[]arr){
int i=0;
int j=arr.length-1;
while(i<j){
int tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
i++;
j--;
}
}
public static String reverse2(int[] arr){
String str="[";
for(int i=arr.length-1;i>=0;i--){
str+=arr[i];
if(i!=0) {
str += ", ";
}
}
str+="]";
return str;
}
输出结果为:
4.8 数组数字排列
public static void main(String[] args) {
//数组数字排列:将偶数放在数组前半部分、奇数放在数组后半部分
int[] array={1,2,3,4,5,6};
transform(array);
System.out.println("transform: "+Arrays.toString(array));
int[] array2=transform2(array);
System.out.println("transform2: "+Arrays.toString(array2));
}
public static void transform(int[] arr){
int i=0;
int j=arr.length-1;
while(i<j){
//i遇到奇数停止++,j遇到偶数停止--
while(i<j&&arr[i]%2==0){
i++;
}//arr[i]一定是偶数
while(i<j&&arr[j]%2!=0){
j--;
}//arr[j]一定是奇数
int tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
}
public static int[] transform2(int[] arr){
int[] arr2=new int[arr.length];
int i=0;
int j=arr.length-1;
for(i=0;i<arr.length-1;i++){
if(arr[i]%2==0){
arr2[i]=arr[i];
}
}
for(j=arr.length-1;j>=0;j--){
if(arr[j]%2!=0){
arr2[j]=arr[j];
}
}
return arr2;
}
输出结果为:
4.9 数组的拷贝
public static void main(String[] args) {
int[] array={1,2,3,4,5,6};
int[] copy1=copy1(array);
System.out.println("Original array: "+Arrays.toString(array));
//copy1 为自定义拷贝方法
System.out.println("copy1 array: "+Arrays.toString(copy1));
//copy 为java自带工具方法:
//参数为待拷贝数组与拷贝长度(一般为数组本身长度或其整数倍数)
int[] copy = Arrays.copyOf(array,array.length);
System.out.println("copy array: "+Arrays.toString(copy));
//java自带的部分拷贝方法(左闭右开)
int[] copy2=Arrays.copyOfRange(array,1,3);
System.out.println("copy2 array: "+Arrays.toString(copy2));
//另外一种部分拷贝方法:System.arraycopy方法
int[] copy3= new int[array.length];
System.arraycopy(array,0,copy3,0,array.length);
System.out.println("copy3 array: "+Arrays.toString(copy3));
//数组调用产生副本clone方法
int[] copy4=array.clone();
System.out.println("copy4 array: "+ Arrays.toString(copy4));
}
public static int[] copy1(int[] arr){
int[] arr2=new int[arr.length];
for(int i=0;i<arr.length;i++){
arr2[i]=arr[i];
}
return arr2;
}
输出结果为:
5. 二维数组
二维数组本质上也是一维数组,只不过每个元素又是一个一维数组;
(1)二维数组的定义:
int[][] array1 = {{1,2,3},{4,5,6}}; //[][] 中不能填充数据
int[][] array2 = new int[][]{{1,2,3},{4,5,6}};
int[][] array3 = new int[2][3];
//java规定必须手动规范行和列元素
(2)二维数组的遍历打印:
public static void main(String[] args) {
int[][] array={{1,2,3},{4,5,6}};
for(int i=0;i<array.length;i++){
for(int j=0;j<array[i].length;j++){
System.out.print(array[i][j]+" ");
}
System.out.println();
}
System.out.println("--------");
for(int[] arr:array){
for(int x:arr){
System.out.print(x+" ");
}
System.out.println();
}
System.out.println("--------");
System.out.println(Arrays.deepToString(array));
}
输出结果为:
注:(1)特殊二维数组的遍历:
int[][] array2=new int[2][];
for(int i=0;i<array2.length;i++){
for(int j=0;j<array2[i].length;j++){
System.out.print(array2[i][j]+" ");
}
System.out.println();
}
运行上文代码,报错如下:
因为java的二维数组可以省略列定义,故而当定义二维数组array2=int[ 2 ] [ ] 时,实际上array2数组是一个两个元素均为null的数组,此时调取array2.length或array2[i].length时,就会出现空指针错误;
(2)定义不规则数组:
int[][] array2=new int[2][];
//定义不规则数组
array2[0]=new int[3];
array2[1]=new int[2];