java Array数组_1

一、数组的基本知识

1.1 引入数组

功能:从键盘输入10个学生的分数,求和,并求平均分,输出。
思路1:定义一个变量sum、avg,分别存储总分、平均分;定义10个变量score1、score2、score3…score10,分别存储一个分数。
缺点:定义的变量太多。
在这里插入图片描述
思路2:定义一个变量sum、avg,分别存储总分、平均分;定义1个变量score,依次存储一个分数。借助循环,完成功能。
缺点:不能同时存储10个分数。
在这里插入图片描述
思路3:定义一个变量sum、avg,分别存储总分、平均分;定义一个数组,由10个元素组成,每个元素相当于是1个变量,总体构成一个更大的变量。
在这里插入图片描述
优点:变量只有一个scoreArr,也可以同时存储10个分数
数组是相同类型数据的有序集合。数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据称作一个元素element,每个元素可以通过一个索引index(下标)来访问它们。数组的基本特点
1. 长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
2. 在内存中分配连续的空间,每个元素占用的空间大小是相同的
3. 同一个数组其元素的类型必须是相同类型,不允许出现混合类型。
4. 数组类型可以是任何数据类型,包括基本类型和引用类型。
5. 数组变量属于引用数据类型

1.2 声明数组

type[] arr_name;  //方式一(推荐使用这种方式)
type  arr_name[]; //方式二
public class Test1{
	public static void main(String[] args){
		* 数组 多个性质相同或者相近的数据的集合  array
        * java数据类型  基本数据类型 八个
        *              引用类型     String  array
        * */
        /*
        * 数组的声明和创建
        * int[] arr; 推荐
        * int ar[];
        * 数组中的每个数据叫做元素
        * */
        int[] arr={5,7,56,85,13,54,95,51};
                // 0 1  2  3  4  5  6  7
        // 数组的长度属性 数组中能装多少个元素 长度属性是int值 数组的长度一旦创建就不可以改变了
        int l =arr.length;
        System.out.println(l);
        // 数组拥有索引属性 索引 index 就是元素的编号 从0开始,从前向后依次递增
        // 根据索引或者数组中的指定的元素
        int e=arr[5];
        System.out.println(e);
        // 数组中的元素是可以修改的
        arr[5]=100;
        System.out.println(arr[5]);

        for (int i=0;i<arr.length;i++){
            System.out.println(arr[i]);
        }

	}
}

注意事项
 声明的时候并没有实例化任何对象,只有在实例化数组对象时,JVM才分配空间,这时才与长度有关。
 声明一个数组的时候并没有数组真正被创建。
 构造一个数组,必须指定长度。

1.3 数组的初始化

数组的初始化方式总共有三种:静态初始化、默认初始化、动态初始化。

1 静态初始化
声明数组、分配空间、元素赋值合并在一起实现。

int [] scoreArr = new int[] {10,20,30,70,60,79,45,34,23,100} ;
int[] scoreArr = {10,20,30,70,60,79,45,34,23,100};
int[] scoreArr = new int[10]{10,20,30,70,60,79,45,34,23,100};//该方式是错误的

2 默认初始化

int a2[] = new int[2];    //默认值是0,0
boolean[] b = new boolean[2];   //默认值: false,false
String[] s = new String[2];    //默认值:null,null

3.动态初始化
元素的赋值和声明数组、分配空间分开实现

int []  scoreArr = new int[10];
scoreArr[0] = 56;
scoreArr[1] = 78;
scoreArr[9] = 100;
测试代码
public class Test2 {
    public static void main(String[] args) {
        // 静态初始化  静态创建 在创建数组的时候支架将元素的值自定义指定
        //double[] arr={10.1,4.56,6.12,3.14,5.23,6.0,7.1};//声明和创建必须在同一行
                    //  0    1     2   3    4   5    6
        double[] arr;
        arr=new double[]{10.1,4.56,6.12,3.14,5.23,6.0,7.1};// 声明和创建可以分开
        //double[] arr =new double[10]{1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10.1};// 错误的
        for (int i = 0; i <arr.length ; i++) {
            System.out.println(arr[i]);
        }

        // JVM自动初始化 动态创建 创建数组时,仅仅规定数组的长度(容量) 元素的值交给JVM自动初始化
        /*
        * byte short int long  0
        * char \u0000 ' '
        * float double 0.0
        * boolean false
        * String 引用类型  null 空引用
        * */
        char[] carr=new char[10];
        for (int i = 0; i <carr.length ; i++) {
            System.out.println(carr[i]);// \u0000
        }
        String[] iarr=new String[10];
        for (int i = 0; i < iarr.length; i++) {
            System.out.println(iarr[i]);
        }
    }
}

1.4 数组内存分配

1. 声明数组
在方法中声明的基本数据类型的变量,仅仅占用栈内存的空间,引用类型的数据创建时,会占用堆内存,但是声明变量不会在堆内存中产生空间的占用

public static void main(String[] args) {
    String s;
    int[] arr;
}

在这里插入图片描述
2.给数组分配空间
1基本数据类型的变量在方法中创建完毕后,仅仅占用栈内存,引用类型要占用两个空间,堆内存上存放数据,栈内上引用堆内存上的地址
2 数组的元素在内存上是连续的
3 栈内存上存储的是数组首元素的地址

public static void main(String[] args) {
    int i=10;
    String s="asdf";
    int[] arr={5,7,1,6,8};
}

在这里插入图片描述

3.给数组元素赋值

public static void main(String[] args) {
    int i=10;
    String s="asdf";
    int[] arr=new int[5];
    
}

在这里插入图片描述

arr[0]=5;
arr[1]=6;
arr[2]=7;
arr[3]=3;
arr[4]=1;

在这里插入图片描述

总结:
1.栈内存

  1. stack memory
  2. 存放局部变量、数组名,没有默认值
  3. 每调用一个方法会开辟一个栈帧,方法执行完立刻回收该栈帧,后进先出

2.堆内存

  1. heap memory
  2. 存放真正的数组元素,有默认值
  3. 方法执行完毕后不会立刻释放资源,由垃圾回收器负责回收;程序员不用操心 但时间不确定

3.数组元素的默认值
在这里插入图片描述

1.5 数组的遍历

JDK1.5提供了增强的for循环功能,可以简化遍历数组的操作,但是不能进行和索引相关的操作,遍历数组过程中不能修改数组中某元素的值。功能其实没有增加。
for循环遍历数组

public class Test3{
	public static void main(String[] args){
		int[] arr = {5,4,3,1,9,2,7,8,0,6};
		//普通的for循环遍历
		for(int i= 0;i<arr.length;i++){
			system.out.printIn(arr[i]);
		}
	}
}

foreach循环遍历数组

public class Test2 {
    public static void main(String[] args) {
        String[] arr={"asdf","qwer","zxcv","abcd"};
        double[] darr={10.1,2.3,5.6,3.8,4.7};

        // 1.5 增强型for循环   foreach循环
        for(String str:arr){
            System.out.println(str);
        }

        for(double dou:darr){
            System.out.println(dou);
        }
    }
}

foreach循环使用特征

public class Test {
    public static void main(String[] args) {

        double[] darr={10.1,2.3,5.6,3.8,4.7};
        /*
        * 1 for循环通过索引定位元素,可以通过索引修改元素值的
        * 2 foreach 通过中间变量临时存储元素的值,修改中间变量不会对元素造成修改
        * 3 foreach 语法更加简单,没有索引
        * 4 当我们仅仅需要数组中的每个元素,不需要修改元素,也不用索引做其他的事,就可以使用 foreach循环
        * */

        // 修改数组中的元素
        /*for (int i = 0; i < darr.length; i++) {
            darr[i]*=10;
        }*/
        for (double v : darr) {
            v*=10;
        }
        // 遍历数组
        for(double value:darr){
            System.out.println(value);
        }
    }
}

1.6 常见异常

 NullPointerException:空指针异常
 ArrayIndexOutOfBoundsException:数组索引越界异常(超过下界或者上界)

public class Test3 {
    public static void main(String[] args) {
        /*
        * 1 动态创建数组时,中括号中放的是数组的长度(容量),容量一定是int类型 和数组的具体类型无关
        * 2 数组的长度不能是负数,会出现NegativeArraySizeException(创建时)
        * 3 如果数组赋值为null 则代表数组没有在堆内存上创建,此时使用数组会出现异常NullPointerException
        * 4 索引如果越界会出现ArrayIndexOutOfBoundsException
        * */

        String[] arr ={"asdf","qwer","zxcv","aaaa","bbbb","cccc"};
       /* System.out.println(arr[-1]);*/

        for (int i = 0; i <arr.length ; i++) {
            System.out.println(arr[i]);
        }
    }
}

二、数组的常见应用方式

2.1 数组合并

将两个数整数数组合并成一个数组

public class Test4 {
    public static void main(String[] args) {
        int[] arr1={1,2,3,4};
        int[] arr2={11,22,33,44,55,66,77,88,99,1010,2020};
        int[] arr3=combain(arr1,arr2);
        // 遍历数组3
        for (int i : arr3) {
            System.out.println(i);
        }
    }
    // 定义一个方法,将两个整数数组合并并返回
    public static int[] combain(int[] arr1,int[] arr2){
        int[] arr3=new int[arr1.length+arr2.length];

        // 遍历数组1 将元素复制到arr3
        for (int i = 0; i <arr1.length ; i++) {
            arr3[i]=arr1[i];
        }
        // 遍历数组2 将元素复制到arr3
        for (int i = 0; i <arr2.length ; i++) {
            arr3[arr1.length+i]=arr2[i];
        }

        return arr3;
    }
}

2.2 查询数组元素

可以查询指定索引的元素的内容,直接按照索引定位即可;
可以按照指定内容元素的索引,需要逐个比较,直到找到为止,或者比较到数组的末尾也没有找到。

public class Test1 {
    public static void main(String[] args) {
        char[] arr={'a','c','d','g','v','d','c','a','v','x'};
        char element='v';

        int index =firstIndexOf(arr,'v');
        System.out.println(index);
        int index2=lastIndexOf(arr,'v');
        System.out.println(index2);

        // 判断一个数组中是不是有且仅有一个指定的元素
        if(index==-1){
            System.out.println("没有");
        }else if(index==index2){
            System.out.println("一个");
        }else{
            System.out.println("至少两个");
        }
    }
    // 定义一个方法, 在给定数组中查找目标元素,如果找到了 返回元素的第一次出现的索引 如果没找到返回-1
    public static int firstIndexOf(char[] arr,char element){
        for (int i = 0; i <arr.length ; i++) {
            if(arr[i]==element){
                return i;
            }
        }
        return -1;
    }
    // 定义一个方法, 在给定数组中查找目标元素,如果找到了 返回元素的最后一次出现的索引 如果没找到返回-1
    public static int lastIndexOf(char[] arr,char element){
        for (int i = arr.length-1; i>=0 ; i--) {
            if(arr[i]==element){
                return i;
            }
        }
        return -1;
    }
}

总结1:数组按照索引查询数据,效率最高;不管索引是哪个,花费的时间是一样的
原理:分配连续的空间,且每个元素的空间大小是相同的,所以指定索引的元素位置=数组的起始位置+每个元素的大小*索引,无需进行逐个比较。
在这里插入图片描述
总结2:数组按照内容查询数据效率低下;
一般需要从第一个元素逐次比较,直到找到位置;或者比较到数组的最后一个元素也没有找到,则确认无该元素。
如果数组的数据是大小有序的,可以通过折半查找的方式来提高查询效率。

3.3 删除数组元素

删除指定索引的元素

public class Test1 {
    public static void main(String[] args) {
        int[] arr={5,7,3,1,2,6,8,4};
        //数组中目前有多少个有效元素
        int size =arr.length;
        // 删除之前遍历
        for (int i = 0; i <size ; i++) {
            System.out.println(arr[i]);
        }
        // 删除指定索引处的元素
        int index =3;
        // 向前移动元素
        for (int i=index;i<arr.length-1;i++){
            arr[i]=arr[i+1];
        }
        // 将最后一个元素置为0
        arr[arr.length-1]=0;
        // 有效元素减少一个
        size--;

        System.out.println("___________________");
        // 删除之后遍历
        for (int i = 0; i <size ; i++) {
            System.out.println(arr[i]);
        }
    }
}

数组的优点:

  1. 一个数组可以存储多个元素
  2. 按照索引查询元素效率高

数组的缺点:

  1. 按照内容查询元素,效率低下(和按照索引插叙相比,相对慢,但是事实上任然很快)
  2. 进行删除和添加时候需要大量的移动元素,效率低下;
  3. 长度固定

总结:
1数组是一种引用类型的数据,占用堆内存
2 多个元素在堆内存上是连续的
3 根据索引查询元素效率非常高
4 增删元素效率非常低

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值