java基础---8. 数组

1. 数组

  • 数组是一种引用数据类型,除了那8个基本数据类型,其他的都是引用数据类型。
  • 数组当中的数据,类型必须统一
  • 数组的长度在程序运行期间不可以改变
  • 无论是基本类型还是引用类型都可以作为数组中的数据

1.1 动态初始化数组--->int[] arrayA = new int[300]

  • 在创建数组的时候,直接指定数组中元素的个数
public class Demo01Array {
    public static void main(String[] args) {
        //创建一个数组,里面可以存放300个int数据
        //格式:
        //数据类型[] 数组名 = new 数据类型[数组长度]
        int[] arrayA = new int[300];

        //创建一个数组,可以存放5个字符串
        String[] arrayC = new String[5];
    }
}

1.2 静态初始化数组--->int [] arrayA = new int[] {5, 15, 25}

  • 在创建数组的时候,不直接指定数据个数多少,而是直接将具体的数据内容进行指定
    静态初始化的数组也是有长度的
public class Demo02Array {
    public static void main(String[] args) {
        //直接创建一个数组,里面装的全是int,具体为:5,15,25
        //格式
        //数据类型[] 数组名称 = new 数据类型[] {元素1, 元素2,...}
        int [] arrayA = new int[] {5, 15, 25};

        //创建一个数组,用来装字符串:"hello","world","java"
        String [] arrayB = new String[] {"hello", "world", "java"};
    }
}

1.3 省略格式--->int[] arrayA = {10, 20, 30}

使用静态初始化的时候,格式还可以省略一下。

public class Demo03Array {
    public static void main(String[] args) {
        //省略格式的静态初始化
        //数据类型[] 数组名 = {元素1,元素2,...};
        int[] arrayA = {10, 20, 30};

        //静态初始化的标准格式可以拆分为两步
        int[] arrayB;
        arrayB = new int[] {11, 21, 31};

        //动初始化的标准格式可以拆分为两步
        int[] arrayC;
        arrayC = new int[5];

        //静态初始化的省略格式不可以拆分为两步
        //错误写法
        //int[] arrayD;
        //arrayD = {11, 21, 31};
    }
}

2. 访问数组元素

2.1 静态

public class Demo04Array {
    public static void main(String[] args) {
        int[] array = {10, 20, 30};
        //1. 直接打印数组名 得到的是数组对应的内存地址哈希值。
        System.out.println(array);//[I@50cbc42f
        //[表示数组
        //I表示里面存放的是int类型的
        //50cbc42f是一个16进制数

        //2. 访问数组里元素的索引值从0开始
        System.out.println(array[1]);//20
    }
}

2.2 动态

/*
动态初始化数组的时候,其中的元素会自动拥有一个默认值
如果是整数类型,默认值为0
如果是浮点类型,默认值为0.0
如果是字符类型,默认值为'u0000'。其中u表示Unicode,这表示一个不可见字符,打印也看不见
如果是Boolean类型,默认为false
如果是引用类型,默认为null

注意事项:
静态数组初始化也有默认值,只不过程序立刻将默认值替换为大括号里面的值
 */
public class Demo05Array {
    public static void main(String[] args) {
        int[] array = new int[3];
        System.out.println(array);
        System.out.println(array[0]);//0
        System.out.println(array[1]);//0
        System.out.println(array[2]);//0
    }
}

3. Java的内存

3.1 一个数组的内存图

public class Demo01ArrayOne {
    public static void main(String[] args) {
        int[] array = new int[3];
        System.out.println(array);//[I@50cbc42f
        System.out.println(array[0]);//0
        System.out.println(array[1]);//0
        System.out.println(array[2]);//0
        System.out.println("=================");

        //改变数组当中元素的内容
        array[1] = 10;
        array[2] = 20;
        System.out.println(array);//[I@50cbc42f
        System.out.println(array[0]);//0
        System.out.println(array[1]);//10
        System.out.println(array[2]);//20
    }
}
  • 将public static void main(String[] args)放入方法区,准备将main方法作为程序的起点运行
  • 在方法区中查看main方法的信息,将信息main(String[] args) 加载到栈内存当中,并且为main方法在内存当中开辟一个内存空间,这个动作叫做进栈
  • 在main方法的栈内存空间中创建一个数组int[] array
  • 为数组赋值,在堆里为数组开辟内存空间new int[3],这里会有一个地址值0X666。同时划分出3个小格子。注意:new出来的东西都在堆里
  • 地址值0x666会赋值给堆里的数组array。也就是说栈里面变量array存储的其实是一个地址值。有了这个地址值就可以找到堆中数组的内容。

改变数组当中元素的内容

3.2 两个数组的内存图

public class Demo02ArrayTwo {
    public static void main(String[] args) {
        int[] arrayA = new int[3];
        System.out.println(arrayA);//[I@50cbc42f
        System.out.println(arrayA[0]);//0
        System.out.println(arrayA[1]);//0
        System.out.println(arrayA[2]);//0
        System.out.println("=================");

        arrayA[1] = 10;
        arrayA[2] = 20;
        System.out.println(arrayA);//[I@50cbc42f
        System.out.println(arrayA[0]);//0
        System.out.println(arrayA[1]);//10
        System.out.println(arrayA[2]);//20

        System.out.println("=================");
        int[] arrayB = new int[3];
        System.out.println(arrayB);//[I@75412c2f
        System.out.println(arrayB[0]);//0
        System.out.println(arrayB[1]);//0
        System.out.println(arrayB[2]);//0
        System.out.println("=================");

        arrayB[1] = 100;
        arrayB[2] = 200;
        System.out.println(arrayB);//[I@75412c2f
        System.out.println(arrayB[0]);//0
        System.out.println(arrayB[1]);//100
        System.out.println(arrayB[2]);//200

    }
}

3.3 两个引用指向同一个数组

public class Demo03ArraySame {
    public static void main(String[] args) {
        int[] arrayA = new int[3];
        System.out.println(arrayA);//[I@50cbc42f
        System.out.println(arrayA[0]);//0
        System.out.println(arrayA[1]);//0
        System.out.println(arrayA[2]);//0
        System.out.println("=================");

        arrayA[1] = 10;
        arrayA[2] = 20;
        System.out.println(arrayA);//[I@50cbc42f
        System.out.println(arrayA[0]);//0
        System.out.println(arrayA[1]);//10
        System.out.println(arrayA[2]);//20

        System.out.println("=================");
        //将arayA数组的地址值赋值给arrayB
        int[] arrayB = arrayA;
        System.out.println(arrayB);//[I@50cbc42f
        System.out.println(arrayB[0]);//0
        System.out.println(arrayB[1]);//10
        System.out.println(arrayB[2]);//20
        System.out.println("=================");

        arrayB[1] = 100;
        arrayB[2] = 200;
        System.out.println(arrayB);//[I@50cbc42f
        System.out.println(arrayB[0]);//0
        System.out.println(arrayB[1]);//100
        System.out.println(arrayB[2]);//200

        //再次访问arrayA
        //由于arrayA和arrayB数组地址相同,它们引用的是一个数组,修改任意一个会堆另一个造成影响
        System.out.println("=================");
        System.out.println(arrayA[0]);//0
        System.out.println(arrayA[1]);//100
        System.out.println(arrayA[2]);//200

    }
}

3.4 常见问题

数组索引越界异常ArrayIndexOutOfBoundsException

数组索引编号从0开始到“数组长度-1”为止。如果访问数组编号的时候,索引编号不存在,那么将会发生数组索引越界异常。ArrayIndexOutOfBoundsException。

空指针异常NullPointerException
/*
所有的引用类型都可以赋值为一个null值。但是代表其中什么都没有

数组必须进行初始化才可以使用其中的元素,如果只是赋值了一个null,没有进行new创建,
那么将会发生空指针异常NullPointerException
 */
public class Demo01ArrayNull {
    public static void main(String[] args) {
        int[] array = null;
        //array = new int[3];
        System.out.println(array[0]);//NullPointerException
    }
}

3.5 数组的长度.length

public class Demo02ArrayLength {
    public static void main(String[] args) {
        int[] arrayA = new int[3];
        int[] arrayB = {1,1,1,1,11,4,3,5,436,54,5,7,7,87,9,9,87};
        //1. 获取数组长度,会得到一个int数字代表数组长度
        int len = arrayB.length;
        System.out.println(len);//17

        //2. 数组运行期间长度不可改变
        int[] arrayC = new int[3];
        System.out.println(arrayC.length);//3
        arrayC = new int[5];
        System.out.println(arrayC.length);//5
        //为什么两次arrayC.length都可以正常打印呢
        //因为:arrayC只是数组的名字,new出来的才是数组,这里new int[3]和new int[5]实际上是两个数组,
        //实际数据不是存放在名字arrayC栈中的,而是存放在内存堆中的
    }
}

对于第二部分的说明如下

遍历数组:对数组当中的每一个元素进行逐一挨个处理。默认方式就是打印输出。

3.6 数组反转

要求:不使用新数组

  • 自己
public class Demo03ArrayReverse {
    public static void main(String[] args) {
        int[] array = {10,20,3,4,5,6,7};
        for (int i = 0; i<array.length/2; i++){
            int temp = array[i];
            array[i] = array[array.length-1-i];
            array[array.length-1-i] = temp;
        }
        for (int i = 0; i<array.length; i++) {
            System.out.println(array[i]);
        }

    }
}
  • 视频课
public class Demo03ArrayReverse {
    public static void main(String[] args) {
        int[] array = {10,20,3,4,5,6,7};
        for (int min = 0, max = array.length-1; min < max; min++,max--){
            int temp = array[min];
            array[min] = array[max];
            array[max] = temp;
        }
        for (int i = 0; i<array.length; i++) {
            System.out.println(array[i]);
        }

    }
}

3.7 数组名作为方法的参数来传递地址

/*
数组可以作为方法的参数
当调用方法的时候,向方法的小括号进行传参,传递进去的其实是数组的地址值
 */
public class Demo01ArrayParam {
    public static void main(String[] args) {
        int[] array = {10, 20, 30, 40, 50};
        System.out.println(array);//地址值
        //1. 传入地址
        printArray(array);
    }
    public static void printArray(int[] array) {
        System.out.println("printArray接收到的参数是" + array);//2. 接收到的参数也是地址
        for(int i = 0; i < array.length; i++){
            System.out.println(array[i]);//3. 根据地址找到索引号对应的内容
        }
    }
}

3.8 数组名作为方法返回地址

/*
任何数据类型都能作为方法的参数类型或者返回值类型
数组作为方法的参数,传递进去的是数组的地址值
数组作为方法的返回值,返回的是数组的地址值
 */
public class Demo02ArrayReturn {
    public static void main(String[] args) {
        int[] result = cal(10,20,30);
        //2. 接收到的是一个地址
        System.out.println("main方法接收到的返回的数组名是:"+result);//地址
        //3. 根据地址访问数组中的元素
        System.out.println("总和"+result[0]);//60
        System.out.println("平均数"+result[1]);//20
    }
    public static int[] cal(int a, int b, int c){
        int sum = a+b+c;
        int avg = sum/3;
        /*int[] array = new int[2];
        array[0] = sum;
        array[1] = avg;*/
        int[] array = {sum, avg};
        //1. 返回的是一个地址
        System.out.println("cal方法内部数组是:"+array);//地址
        return array;
    }
}
原文地址:https://www.cnblogs.com/deer-cen/p/12195999.html