Java数组的定义和使用

数组

数组:是一块连续的内存,存放相同的数据类型的集合

在java中,数组也叫作数组对象。

1.数组定义

int[] arr ={1,2,3};//静态初始化
int[] arr1=new int[10];//定义了数组,但未初始化,默认值为0
int[] arr2=new int[]{1,2,3};//动态初始化

  • 引用不一定在栈上(局部->栈上),对象一定在堆上。
  • 引用除了在定义时,在之后不能整体初始化。

2.数组的使用

1、数组打印:

import java.util.Arrays;
public class TestDemo {
    public static void main(String[] args) {
        int[] arr ={1,2,3};
        int[] arr1=new int[10];
        int[] arr2=new int[]{1,2,3,4};
        //数组打印方式 1:
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
        System.out.println();
        for (int x:arr2) {
            System.out.print(x+" ");
        }

        System.out.println();
        //打印方式3
        //将数组转化为字符串输出
        String str = Arrays.toString(arr);
        System.out.println(str);
    }
}
//运行结果:
1 2 3 
1 2 3 4 
[1, 2, 3]
  • 使用 arr.length 能够获取到数组的长度。 . 为成员访问操作符。
  • 打印方式 1 可以拿到下标,方式 2 不可以。
  • 方式3中的  Arrays  是一个工具类,专门用来操作数组的工具类。
  • 使用 [ ] 按下标取(或修改)数组元素,需要注意, 下标从 0 开始计数。
  • 下标访问操作不能超出有效范围 [0, length - 1] , 如果超出有效范围, 会出现下标越界异常。

2、下标越界:

int[] arr ={1,2,3};
System.out.println(arr[3]);

   可以看到数组的长度为3,下标为0~2,输出arr[3],运行时会报错,数组下标访问异常。

3、认识 null:

  • null 在 Java 中表示 "空引用"
  • null 的作用类似于 C 语言中的 NULL (空指针), 都是表示一个无效的内存位置.。因此不能对这个内存进行任何读写操 作. 一旦尝试读写, 就会抛出 NullPointerException。
  • arr = null, 代表arr不指向任何对象。

注意: Java 中并没有约定 null 和 0 号地址的内存有任何关联.

4、空指针异常

当arr=null时,再去访问arr[ ]或者求取长度arr.length 时会报错,空指针异常。

int[] arr ={1,2,3};
arr =null;
System.out.println(arr.length);//运行报错:空指针异常
System.out.println(arr[2]);//运行报错:空指针异常

当代码运行时出现如上的空指针异常的报错,可以去检查引用是否等于null。

5、对象回收

int[] arr ={1,2,3};
arr =null;

当引用arr=null时,原对象{1,2,3}被回收;

当对象未被任何引用 引用时,这个对象就会被垃圾回收器回收掉。

 

6、引用不能指向引用,如出现以下,代表 引用arr1 指向了 引用arr 指向的对象。

int[ ] arr  = {1,2,3};

int[ ] arr1= arr;

7、一个引用只能指向一个对象。如出现以下,最终只指向最后一个对象,之前两个没被其他引用 引用时就会被垃圾回收器回收了。

int[ ] arr  = {1,2,3};

arr  = new int[ ]{1,2};

arr  = new int[ ]{1,2,3,4};


3.数组作为方法的参数

单独写一个方法打印数组。

public static void print(int[] a){
        for (int i = 0; i <a.length; i++) {
            System.out.print(a[i]+" ");
        }
        System.out.println();
    }
    public static void main(String[] args) {
        int[] arr={1,2,3};
        print(arr);
    }
//运行结果:1 2 3
  • 在这个代码中 int[] a 是函数的形参, int[ ] arr 是函数实参,如果需要获取到数组长度, 同样可以使用 a.length。
  • 引用a 与arr都指向同一个对象,不管通过哪个引用修改对象的值,另一个引用去访问的时候也会受到影响。(例:如写一个方法swap()交换1,2。)
public class TestDemo {
    public static void swap(int[] a){
        int t=a[0];
        a[0]=a[1];
        a[1]=t;
    }
    public static void main(String[] args) {
        int[] arr= {1,2};
        System.out.println("交换前:arr[0]="+arr[0]+" arr[1]="+arr[1]);
        swap(arr);
        System.out.println("交换后:arr[0]="+arr[0]+" arr[1]="+arr[1]);
    }
}
//运行结果:
交换前:arr[0]=1 arr[1]=2
交换后:arr[0]=2 arr[1]=1

4.数组作为返回值

例1:return可直接返回数组

import java.util.Arrays;
public class TestDemo {
    public static int[] fun(){
        int[] arr={1,2,3};
        return arr;
        //return new int[]{1,2,3}
        //可替换上面两行,效果一致
        //不可直接return {1,2,3}
    }
    public static void main(String[] args) {
        int[] arr1=fun();
        String str=Arrays.toString(arr1);
        System.out.println(str);
    }
}
//运行结果:[1, 2, 3]

例2: 写一个方法, 将数组中的每个元素都 * 2

public class TestDemo {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        int[] arr1=transform(arr);
        printArray(arr1);
    }
    public static void printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }
    public static int[] transform(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] = arr[i] * 2;
        }
        return arr;
    }
}

//运行结果:2 4 6
  • 这个代码固然可行, 但是破坏了原有数组.arr,有时候我们不希望破坏原数组, 就需要在方法transform内部创建一个新的数组( int[ ] ret = new int[arr.length] ), 并由 方法返回出来。另外由于数组是引用类型, 返回的时候只是将这个数组的首地址返回给函数调用者, 没有拷贝数组内容, 从而比较高效。

如下:

import java.util.Arrays;
public class TestDemo {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        int[] arr1=transform(arr);
        printArray(arr1);
    }
    public static int[] transform(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 printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }
}
//运行结果:2 4 6

 

5.数组拷贝

方式1:循环拷贝

import java.util.Arrays;
public class TestDemo {
    public static void main(String[] args) {
        int[] arr={1,2,5,9,5,9,5,5,5};
        int[] arr1=new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            arr1[i]=arr[i];
        }
        System.out.println("arr:"+Arrays.toString(arr));
        System.out.println("arr1:"+Arrays.toString(arr1));
    }
}

方式2:

Arrays.copyOf(原数组,拷贝长度)
import java.util.Arrays;
public class TestDemo {
    public static void main(String[] args) {
        int[] arr={1,2,5,9,5,9,5,5,5};
        int[] arr1=Arrays.copyOf(arr,arr.length);
        System.out.println("arr:"+Arrays.toString(arr));
        System.out.println("arr1:"+Arrays.toString(arr1));
    }
}
  • 可实现部分拷贝
Arrays.copyOfRange(原始数组,起始位置,结束为止)//左闭右开式
import java.util.Arrays;
public class TestDemo {
    public static void main(String[] args) {
        int[] arr={1,2,5,9,5,9,5,5,5};
        int[] arr1=Arrays.copyOfRange(arr,2,5);//左闭右开式,包含左边不包含右边
        System.out.println("arr:"+Arrays.toString(arr));
        System.out.println("arr1:"+Arrays.toString(arr1));
    }
}
//运行结果:
arr:[1, 2, 5, 9, 5, 9, 5, 5, 5]
arr1:[5, 9, 5]

方式3:比方式2快

System.arraycopy(原来的数组,原来数组的位置,目的地的数组,目的地数组位置,拷贝长度);
import java.util.Arrays;
public class TestDemo {
    public static void main(String[] args) {
        int[] arr={1,2,5,9,5,9,5,5,5};
        int[] arr1=new int[arr.length];
        System.arraycopy(arr,0,arr1,0,arr.length);
        System.out.println("arr:"+Arrays.toString(arr));
        System.out.println("arr1:"+Arrays.toString(arr1));
    }
}

方式4:

int[] arr1=arr.clone()
import java.util.Arrays;
public class TestDemo {
    public static void main(String[] args) {
        int[] arr={1,2,5,9,5,9,5,5,5};
        int[] arr1=arr.clone();//产生当前引用的副本
        System.out.println("arr:"+Arrays.toString(arr));
        System.out.println("arr1:"+Arrays.toString(arr1));
    }
}

这四种拷贝方式是深拷贝还是浅拷贝?

      简单类型:深拷贝;引用类型:浅拷贝

       拷贝后通过修改arr1(拷贝后的新数组)指向的对象,不会影响arr(原数组)所指向的对象,是深拷贝,反之。

6.二维数组

二维数组本质上也就是一维数组, 只不过每个元素又是一个一维数组

数据类型[ ][ ]    数组名称 = new  数据类型 [行数][列数] { 初始化数据 };

int[ ][ ]   arr={{1,2,},{3,4}};( [ ][ ]什么都不能写 )

int[ ][ ]   arr1= new int[2][3];//默认为0

int[ ][ ]   arr2= new int[2][];//行不可以省略,列可以

int[ ][ ]   arr3= new int[ ][ ]{{1,2,},{3,4}};( [ ][ ]什么都不能写 )

打印示例:(按需求选择)

打印1:

import java.util.Arrays;
public class TestDemo {
    public static void main(String[] args) {
        int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
        for (int row = 0; row < arr.length; row++) {
            for (int col = 0; col < arr[row].length; col++) {
                System.out.printf("%d\t", arr[row][col]);
            }
            System.out.println("");
        }

    }
}
//运行结果
1	2	3	4	
5	6	7	8	
9	10	11	12	

打印2:

import java.util.Arrays;
public class TestDemo {
    public static void main(String[] args) {
        int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
        for(int[] arr1:arr){
            for (int x : arr1) {
                System.out.print(x+" ");
            }
            System.out.println();
        }
    }
}

打印3:

import java.util.Arrays;
public class TestDemo {
    public static void main(String[] args) {
        int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
        String ret = Arrays.deepToString(arr);
        System.out.println(ret);
    }
}
//运行结果:[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值