不就是Java吗之数组的定义和使用

一、数组的基本概念

1.1 什么是数组?

image-20220608150208505

数组是存放相同数据类型的集合,在内存中是一段连续的内存空间

1.2 数组的创建和初始化

1.2.1 创建

public static void main(String[] args) {
        //1.中括号里面不能有数字
        int[] array1 = {1,2,3,4,5};//最常用
        //2.中括号里面不能有数字
        int[] array2 = new int[]{1,2,3,4,5};//跟第一种一样,写法更复杂
        //3.不确定数组具体元素
        int[] array3 = new int[10];//未初始化,里面默认为0
        array3[0] = 1;//初始化要这样
        
    }
public static void main(String[] args) {
        double[] array = new double[10];//每个元素都是0
        String[] array2 = new String[10];//Java里面支持字符串数组,他的每个值初始化都是null
    	boolean[] array3 = new Boolean[10];//默认都是false
    }

1.2.2 初始化

1.2.2.1 动态初始化

未指定元素具体值

int[] array = new int[10];//未指定元素具体
1.2.2.2 静态初始化

定义的同时并初始化

int[] array = new int[]{0,1,2,3};//定义的同时并初始化
1.2.2.3 注意事项
  1. 静态初始化虽然没有指定数组的长度,编译器在编译时会根据{}中元素个数来确定数组的长度。

  2. 静态初始化时,{}中数据类型必须与[]前数据类型一致。

  3. 静态初始化可以简写,省去后面的new 类型[]。但是编译的时候,还是会还原回来的

  4. 其实数组创建也可以用C语言的形式

    int array[10] = {1,2,3};
    
  5. 不确定数组具体内容,使用动态初始化(即创建方法3)

  6. 初始化也可以分成两行写

    int[] array1;
    array = new int[10];
    
    int[] array2;
    array2 = new int[]{1,2,3};
    
    //这种写法不能省略new int[],否则会编译失败
    

    image-20220608203919527

    另外,不简写的话,可以重复定义多次

    int[] array1;
    array1 = new int[]{1,2,3};
    array1 = new int[]{11,22,33};
    

1.3 数组的使用

1.3.1 数组中元素的访问

数组在内存中是一段连续的空间,下标是从0开始的,数组可以通过下标来访问任意位置的元素

image-20220608204526769

public static void main(String[] args) {
        int[] array = {1,2,3,4,5};
        //1.既可以通过下标访问元素
        System.out.println(array[3]);//访问下标为3,实际上值为4的元素
        //2.又可以通过下标修改元素
        array[4] = 55;//下标为4,实际上值为5的元素被修改成了55
        System.out.println(array[4]);
    }

要注意,不要越界

public static void main(String[] args) {
        int[] array = {1,2,3,4,5};//数组长度为5,最大下标为4
        System.out.println(array[99]);//严重越界!!!
    }

image-20220608210124786

1.3.2 遍历数组

两种方式

  1. for循环:快捷键for+i

  2. for-each循环:加强版的for循环

    public static void main(String[] args) {
            int[] array = {1,2,3,4,5};
       		//在数组中,我们可以通过 数组对象.length 来获取数组长度
            //方式1:for循环遍历
            for (int i = 0; i < array.length; i++) {
                System.out.println(array[i]);
            }
            //方式2:for-each循环
            //不仅可以打印数组,还可以打印集合当中的元素
            //而且不需要用到下标
            for (int x : array) {
                System.out.print(x + " ");//其实就是把数组元素对应的值赋给x,然后打印x
            }
            System.out.println();
        }
    

    image-20220608211235658

我们还可以通过Java官方提供的工具打印数组

public static void main(String[] args) {        
        //Arrays:工具类->帮助我们操作数组,他的返回值是String
        String ret = Arrays.toString(array);
        System.out.println(ret);
        //直接可以写成一句
        //System.out.println(Arrays.toString(array));
    }

二、数组是引用类型

2.1 初识JVM的内存分布

首先,我们先了解一下:引用

引用是一个变量,里面存储的是地址

int[] array = {1,2,3,4};//array1这个引用,引用了(指向了) {1,2,3,4}这个对象
//引用和指向代表的是一个意思

那么,我们再来看一下初识JVM的内存分布

image-20220608212913017

Java虚拟机栈:我们常说的栈(局部变量…)

Java本地⽅法栈:运⾏⼀些由C/C++代码编写的程序【JVM其实是⼀个软件,是⼀个由C/C++代码编写的软件】

堆:只要是对象,都在堆上分配内存(数组…)

程序计数器:存放⼀些指令

方法区:静态的成员变量…

划分内存的好处:方便管理

image-20220608213155612

image-20220608213825738

我们来看这段代码

public static void main(String[] args) {
        int[] array = {1,2,3};
        System.out.println(array);//[I@1b6d3586
    }

image-20220608224223870

2.2 基本类型变量与引用类型变量

基础类型变量,存放的是数值

引用类型变量,存放的是地址

1.当两个数组指向同一块内存空间时

public static void main(String[] args) {
        int[] array1 = {1,2,3,4};
        int[] array2 = array1;//array2 引用了 array1 引用的对象(不是引用指向引用)
        System.out.println("array1" + Arrays.toString(array1));
        System.out.println("array2" + Arrays.toString(array2));

        System.out.println("-------------------");

        array2[0] = 100;
        System.out.println("array1" + Arrays.toString(array1));
        System.out.println("array2" + Arrays.toString(array2));
    }

image-20220608225238121

image-20220608225714649

2.数组内容相同,不代表他们俩就一模一样

public static void main(String[] args) {
        int[] array1 = {1,2,3,4};
        int[] array2 = {1,2,3,4};
        System.out.println(array1);
        System.out.println(array2);//两个数组地址不同
    }
//备注:new出来的就是新的

image-20220608225842349

image-20220608230151630

2.3 再谈引用变量

public static void main(String[] args) {
        int[] array1 = new int[3];
        array1[0] = 10;
        array1[1] = 20;
        array1[2] = 30;

        int[] array2 = new int[]{1,2,3,4,5};
        array2[0] = 100;
        array2[1] = 200;

        array1 = array2;
        array1[2] = 300;
        array1[3] = 400;
        array1[4] = 500;

        System.out.println(Arrays.toString(array2));
    }

image-20220609195409149

2.4 关于null

null代表不指向任何对象

当数组被赋值为null的时候,针对他的操作,都会造成空指针异常

public static void main(String[] args) {
        int[] array = null;//引用类型赋值为null->代表array这个引用不指向任何对象,这时候对他进行操作,就会空指针异常
        array[0] = 1;
        System.out.println(array.length);
    }

image-20220608225001644

注意:在Java中,并没有约定null跟0号地址的内存有关联

小猫分隔符

小结:

  1. 引用能指向引用吗?

    不能!引用只能指向对象

    array1 = array2;//代表array1这个引用 引用了(指向了)array2所引用的对象
    
  2. ⼀个引用能同时指向多个对象吗?

    不能同时.一个引用只能同时指向一个对象

    image-20220609200536037

  3. 引用一定在栈上吗?(就是我们画的两个框框,左边的那个)

    不是的.现在之所以把它画在栈上,是因为我们目前只是接触到局部变量,还没有接触成员变量,后面会接触到

    public class Main {
        public int[] array = {1,2,3,4,5,6,7,8};//成员变量->在堆上
        
        public static void main7(String[] args) {
            int[] array1 = {1,2,3,4};//局部变量->在栈上
            array1 = new int[]{11,12,13,14};
            array1 = new int[]{6,7,8,9};
    }
    
  4. 引用赋值为null代表啥?

    int[] array = null;//代表这个引用 不指向任何对象
    

三、数组的使用

3.1 保存数据

public static void main(String[] args) {
        int[] array = {1,2,3,4,5};
   		
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }

3.2 作为函数的参数

3.2.1 参数为基本数据类型

我们之前在方法的时候讲过,形参的改变不会影响实参

public class TestDemo2 {
    public static void func(int a) {
        a = 20;
    }
    public static void main(String[] args) {
        int x = 10;
        func(x);
        System.out.println(x);
    }
}

image-20220609202041653

那么传过去的数据是数组类型也是这样

3.2.2 参数为引用数据类型

public static void func(int[] arr) {
        arr = new int[]{11,22,33,44};
    }
    public static void main(String[] args) {
        int[] array1 = {1,2,3,4};
        func(array1);
        System.out.println(Arrays.toString(array1));
    }

image-20220609202734090

public static void func(int[] arr) {
        arr[0] = 100;
    }
    public static void main(String[] args) {
        int[] array1 = {1,2,3,4};
        func(array1);
        System.out.println(Arrays.toString(array1));
    }

image-20220609203113927

上面这两种方式,虽然都是传了地址,但是他们干的事不太一样

3.3 作为函数的返回值

public static int[] func5() {
    int[] array = {1,2,3,4};
    return array;
}
public static void main11(String[] args) {
    int[] ret = func5();//返回的是数组,用数组接收
    System.out.println(Arrays.toString(ret));
}

image-20220609203654567

四、数组的相关练习

4.1 数组转字符串

写⼀个函数将 数组以字符串的形式进行输出 [1, 2, 3, 4]

public class TestDemo1 {
    public static String myToString(int[] array) {
        String ret = "[";
        for (int i = 0; i < array.length; i++) {
            ret += array[i];
            if(i != array.length - 1) {
                ret += ",";
            }
        }
        ret += "]";
        return ret;
    }
    public static void main(String[] args) {
        int[] array = {1,2,3,4};
        String ret = myToString(array);
        System.out.println(ret);
    }
}

当然,我们还可以调用Arrays下面的toString

public static void main(String[] args) {        
        //Arrays:工具类->帮助我们操作数组,他的返回值是String
        String ret = Arrays.toString(array);
        System.out.println(ret);
        //直接可以写成一句
        //System.out.println(Arrays.toString(array));
    }

4.2 数组的拷贝

数组拷贝

方法一:使⽤for循环进行拷贝

public static void main13(String[] args) {
    int[] array = {1,2,3,4};
    int[] copy = new int[array.length];
    for (int i = 0; i < array.length; i++) {
        copy[i] = array[i];
    }
    System.out.println(Arrays.toString(copy));
}

方法二:Arrays.copyOf(你要拷贝的数组,新的长度)

public static void main14(String[] args) {
    int[] array = {1,2,3,4};
    //虽然是发⽣了拷贝 也可以看做是 扩容
    int[] copy = Arrays.copyOf(array,array.length);
    int[] ret = Arrays.copyOfRange(array,1,3);//这种方法需要接收返回值
    System.out.println(Arrays.toString(copy));//[1,2,3,4]
    System.out.println(Arrays.toString(ret));//[2,3]
}

方法三:System.arraycopy你要拷贝的数组,开始拷贝的下标,目的地数组,目的地数组的位置,你要拷贝的长度

public static void main15(String[] args) {
    int[] array = {1,2,3,4};
    int[] copy = new int[array.length];
    System.arraycopy(array,0,copy,0,array.length);
    System.out.println(Arrays.toString(copy));
}

方法四:array.clone() 产生了一个新的副本

public static void main(String[] args) {
    int[] array = {1,2,3,4};
    int[] copy = array.clone();
    System.out.println(Arrays.toString(copy));
    System.out.println(array);
    System.out.println(copy);
}

4.3 求数组中元素的平均值

public static double avg(int[] array) {
    int sum = 0;
    for (int i = 0; i < array.length; i++) {
        sum = sum + array[i];
    }
    return sum*1.0 / array.length;
}

4.4 顺序查找

public static int search(int[] array,int key) {
    for (int i = 0; i < array.length; i++) {
        if(array[i] == key) {
            return i;
        }
    }
    //如果代码走到这里,要不是没进去for循环,要不就是没找到
    return -1;//返回-1->因为数组没有负数下标
}
  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加勒比海涛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值