Java从入门到放弃05(上)---数组Java中的内存分配/栈/堆

Java从入门到放弃05—数组/Java中的内存分配/栈/堆

1.概念

  • 数组是存储同一种数据类型多个元素的集合。可以将数组看成是一个容器。
  • 数组既可以存储基本数据类型,也可以存储引用数据类型。

2.定义格式及数组的初始化

  • Java中的数组必须先初始化,才能使用。初始化就是为数组中的数组元素分配内存空间,并为数组的每个元素赋值。
  • 数组的初始化方式有两种:动态初始化/静态初始化。(注:两种方式每次只能使用一种,不可以动静结合。)下面以程序说明两种方式的不同:
class ArrayPractice01{
    public static void main(String[] args){
        int[] arr1=new int[3];//动态初始化:只定义数组的长度,由系统赋默认值。数组创建好后,由系统分配索引脚标,从0开始到数组长度-1.
        int num=arr1[2];//取出数组中的元素/注意打印和取出的区别。
        System.out.println("数组arr1中索引脚标为2的元素为"+arr1[2]);//打印数组中索引脚标为2的元素
        int[] arr2={1,2,3,4,5};//静态初始化:为数组赋值,由系统计算数组长度。
        int length=arr2.length;//数组的长度属性
        System.out.println("数组arr2的长度是"+length);
        }
}
运行结果:数组arr1中索引脚标为2的元素为0
		数组arr2的长度是5
  • 常见数组异常

a.空指针异常(原因:数组已经不在指向堆内存了。而你还用数组名去访问元素。)

class ArrayPractice02{
    public static void main(String[] args){
        int[] arr={10,20};
        arr=null;//人为置空
        int length=arr.length;
        System.out.println(length);
    }
}
运行结果:NullPointerException (翻译:空指针异常)

b.数组脚标越界异常(原因:你访问了不存在的索引。)

class ArrayPractice03{
    public static void main(String[] args){
        int[] arr=new int[5];
        int num=arr[arr.length];//数组中的最后一个元素索引=数组长度-1,因此该程序会报错
        System.out,println(num);
    }
}
运行结果:ArrayIndexOutOfBoundsException 数组角标越界异常

3.Java中的内存分配以及栈和堆的区别

  • 栈:存放局部变量。(局部变量:在方法定义中或者方法声明上的变量都是局部变量)

  • 堆:存放所有new出来的东西

    a.每一个new出的东西都会在堆中分配到一个地址值

    b.不同类型的变量都有对应的默认值

     ~~~
    

    byte/short/int/long ------- 0
    float/double ------- 0.0
    char ------- ‘\u0000’
    boolean ------- false
    引用数据类型 ------- null
    ~~~

    c.地址值和使用完毕后就变成了垃圾,等待Java的回收算法对其回收

  • 方法区:(面向对象部分讲解)

  • 本地方法区:(和系统相关)

  • 寄存器(CPU使用)

  • 由三个数组只引用两个地址值的程序为例,具体说明内存分配过程:

    class ArrayPractice04{//1.方法区生成ArrayPractice04.class文件
        public static void main(String[] args){//2.栈开始执行main{}
            int[] arr1=new int[3];//3.由于new了一个新数组,因此堆为arr1分配内存空间,为数组赋默认值0,并返回地址值,如0x0001。
            arr1[0]=10;//4a.根据地址值,对arr1[0]重新赋值,将默认值覆盖。
            arr1[1]=20;//4b.根据地址值,对arr1[1]重新赋值,将默认值覆盖。
            int[] arr2=new int[3];//5.由于new了一个新数组,因此堆为arr2重新分配内存空间,为数组赋默认值0,并返回地址值,如0x0002。
            arr2[1]=34;//5a.根据地址值,对arr2[1]重新赋值,将默认值覆盖。
            arr2[2]=89;//5b.根据地址值,对arr2[2]重新赋值,将默认值覆盖。
            int[] arr3=arr1;//6.没有new,因此堆不会重新分配内存空间,将数组arr1的地址值赋值给数组arr3,此时arr3与arr1元素相同。
            arr3[0]=78;//7.由于arr3和arr1引用同一个地址值,对arr3[0]重新赋值会将arr1[0]原先的值覆盖掉,因此导致arr1[0]的值也发生改变。
            arr3[1]=28;//同理,arr3[1]的重新赋值会导致arr1[1]发生改变。
            arr3[2]=99;//同理,arr3[2]的重新赋值会导致arr1[2]发生改变。
            System.out.println("arr1[0]="+arr1[0]);//78
            System.out.println("arr1[1]="+arr1[1]);//28
            System.out.println("arr1[2]="+arr1[2]);//99
            System.out.println("arr2[0]="+arr2[0]);//0
            System.out.println("arr2[1]="+arr2[1]);//34
            System.out.println("arr2[2]="+arr2[2]);//89
            System.out.println("arr3[0]="+arr3[0]);//78
            System.out.println("arr3[1]="+arr3[1]);//28
            System.out.println("arr3[2]="+arr3[2]);//99
        }
    }
    运行结果:	     arr1[0]=78
    				arr1[1]=28
    				arr1[2]=99
                    arr2[0]=0
                    arr2[1]=34
                    arr2[2]=89
                    arr3[0]=78
                    arr3[1]=28
                    arr3[2]=99
    

    4.数组的操作

    01 遍历(依次输出数组中的每个元素)

    class ArrayPractice05{
        public static void main(String[] args){
            int[] arr={10,20,30,40,50};
            System.out.println("------正向遍历------");
            for(int i=0;i<=arr.length-1;i++){
                System.out.print(arr[i]+"\t");
            }
            System.out,println();
            System.out.println("------反向遍历------");
            for(int j=arr.length-1;j>=0;j--){
                System.out.print(arr[j]+"\t");
            }
        }
    }
    运行结果:---------- 运行 ----------
    			------正向遍历------
    			10	20	30	40	50	
    			------反向遍历------
    			50	40	30	20	10	
    		输出完成 (耗时 0 秒) - 正常终止
    

    02 获取最值

    class ArrayPractice06{
        public static void main(String[] args){
            int[] arr={32,45,87,23,65};
            int max=arr[0];
            for(int i=1;i<=arr.length-1;i++){
                max=max>arr[i]?max:arr[i];
            }
            System.out.println("数组arr中最大的元素是"+max);
        }
    }
    运行结果:数组arr中最大的元素是87
    

    03 数组元素反转(将数组中的元素进行对调,按倒序输出)

    class ArrayPractice07{
        public static void main(String[] args){
            int[] arr={109,89,40,34,57,99};
            int t=0;
            for(int i=0,j=arr.length-1;i<j;i++,j--){
                t=arr[i];
                arr[i]=arr[arr.length-1-i];
                arr[arr.length-1-i]=t;
            }
            for(int j=0;j<=arr.length-1;j++){
                System.out.print(arr[j]+"\t");
            }
        }
    }
    运行结果:99	57	34	40	89	109	
    

    04 查表法

    a.根据索引查元素

    import java.util.Scanner;
    class ArrayPractice08{
        public static void main(String[] args){
           String[] str={"星期一","星期二","星期三","星期四","星期五","星期六","星期日"};
            Scanner sc=new Scanner(System.in);
            System.out.println("请在1---7之间选择你想输入的索引");
            int index=sc.nextInt();
            String weekname=getWeekname(index,str);
            System.out.println(weekname);
        }
        public static String getWeekname(int index,String str[]){
            if(1<=index&&index>=7){
                String weekname=str[index-1];
    			return weekname;
            }else{
                return "输入的索引有误";
            }
        }
    }
    

    b.根据元素查索引

    import java.util.Scanner;
    
    public class ArrayDemo10 {
        public static void main(String[] args){
            String[] str={"星期一","星期二","星期三","星期四","星期五","星期六","星期日"};
            Scanner Wname=new Scanner(System.in);
            System.out.println("请输入关键字/例:星期一");
            String name=Wname.nextLine();//String类型数据的录入程序格式
            int index = getIndex(name, str);
            System.out.println("您查找的索引号为:"+index);
        }
        public static int getIndex(String name,String[] str){//注意返回值类型要与方法中定义的返回值类型保持一致
            for(int i=0;i<=str.length-1;i++){
                if(name.equals(str[i])){//String类型数据之间比较相等的语句**.equals(***)
                    return i;
                }
            }
            return -1;//通常用-1表示未查找到
        }
    }
    

猜你喜欢

转载自blog.csdn.net/yinyanyao1747/article/details/89003558