小白Java笔记——深入数组
来源:互联网 发布:卓行信贷网络借贷 编辑:程序博客网 时间:2024/06/01 21:50
前言:前面说过数组是一个引用数据类型,数组引用变量只是一个引用,数组元素和数组变量是分开存放的。正如定义数组的时候,只是定义一个引用变量,还需要再初始化。
一、内存中的数组
- 数组引用变量(就是一开始定义的)只是一个引用,它可以指向任何有效的内存(只要你给他初始化,说明它需要指向哪里)。换句话说,只有引用变量指向有效的内存空间,才可以通过该数组变量来访问数组元素(也就是内存里的内容)。
- 与所有引用变量相同的是,引用变量是访问真是对象的根本方式(如果想访问数组本身,只能通过这个数组的引用变量来访问它)。
关于数组的储存:实际的数组对像储存在堆(heap)内存中;如果引用该数组对象的数组引用变量是一个局部变量,则存储在栈(stack)内存中,如图:
也就是如果要访问图中的数组P,就只能通过P[index]的形式实现。关于堆内存和栈内存详情看https://www.cnblogs.com/SaraMoring/p/5687466.html
简单理解看下面:
关于栈内存和堆内存:
栈内存:用于一些基本类型的变量数据和对象的引用变量的存储;
堆内存:存放由new创建的对象和数组。
1 . 栈内存:当一个方法执行,每个方法都会建立自己的内存栈,在这个方法内定义的变量将会逐个放入这块内存栈中,随着方法的执行结束,这个内存栈也将自然销毁。也就是所有方法中定义的局部变量都放在栈内存中;
2 . 堆内存:在程序中创建一个对象时,将被保存在运行时数据区中,也就是堆内存中。堆内存中的对象不会随着方法的的结束而销毁,因为即使方法结束,该对象还可能会被另一个引用变量应用(方法的参数传递常见)。只有当这个对象没有被任何引用变量引用时,系统的垃圾回收才会在适合的时候回收它。
- 由堆内存可以知道,如果想让垃圾回收机制回收一个数组所占的内存空间,可以将数组的变量赋值为null,也就切断了数组引用变量和实际数组之间的联系。
- 只要类型相互兼容,就可以让一个数组变量指向另一个实际的数组,会让人产生数组的长度可变的错觉。
public class ArrayInRam{ public static void main(String[] args){ //静态 int[] a = {5,7,20}; //动态 int[] b = new int[4]; System.out.println("b长度是:"+ b.length); for(int i=0,len=a.length;i<len;i++){ System.out.println(a[i]);} for(int i = 0,len = b.length;i<len;i++){ System.out.println(b[i]); } //因为a,b都是int[]类型,所以可以将a的值赋给b; //也就是让b引用指向a引用引用指向的数组 b = a; System.out.println("b的长度:"+ b.length);}}
结果:
b长度是:457200000b的长度:3
示意图:
- 看待数组,一定要看成两部分:一个是定义的数组引用变量(例子中的a,b);另一个实际的数组对象(int[]),这一部分是在堆内存运行,通常无法直接使用,只能通过引用变量访问。
二、基本类型数组的初始化
int[] iArr;iArr = new int[4];for(int i = 0 ; i <iArr.length ; i++){ iArr[i] = i + 10;}
过程图:
可以看到定义时,引用变量iArr并没有指向堆内存,因为没有初始化;
上图每个数组元素直接储存在对应的内存中,也就是说操作基本类型数组的数组元素时,实际上相当于操作基本类型的变量。
三、引用类型数组的初始化
- 引用类型数组的元素是引用,每个数组元素里存储的是引用,它指向另一块内存,这个内存里存储了有效数据。
//首先定义一个Person类(所有类都是引用类型,person类想当一个模子)class Person{ public int age; public double height; //注意() public void info(){ System.out.println("我的年龄:"+age+"我的身高:"+height);}}//下面将定义一个Person[]数组,只不过这个数组引用变量名字不是Person,而是student,并为这个数组的每个元素指定值(这个值就是实例化的Person)public class ReferenceArrayTest{ public static void main(String[] args){ //定义一个student数组变量,类型是Person[] Person[] students; students = new Person[2]; //创建person实例,并将这个实例赋给zhang变量 Person zhang = new Person(); zhang.age = 15; zhang.height = 158; //创建person实例,并将这个实例赋给lee变量 Person lee = new Person(); lee.age = 23; lee.height = 180; //下面开始将zhang、lee的值赋给数组元素 students[0] = zhang; students[1] = lee; //下面两行代码结果一样 lee.info(); students[1].info();}}
结果:
我的年龄:23我的身高:180.0我的年龄:23我的身高:180.0
过程图:
- 由图可以看出,最后两行代码结果一样,因为zhang和students[1]变量引用指向同一个内存区。如果修改students[1]所指向的person实例的实例变量,或者是zhang的,所修改的都是同一个内存变量,都会互相影响。
四、没有多维数组
java语言支持多维数组的语法,但如果从数组底层的运行机制来看——没有多维数组;Java语言里数组类型是引用类型,所以数组变量是一个引用,如果数组元素也是引用,指向真实内存,这种形式看起来像多维数组。
public class TwoDimesionTest{ public static void main(String[] args){ //定义一个二维数组,可以看成类型为int[]的一维数组 int[][] a; //把a当成一维数组,初始化长度是4 //a数组元素又是引用类型,也就相当于4个一维数组 a = new int[4][]; //当成一维数组,遍历 for(int i = 0 , len = a.length; i < len ; i++) { System.out.println(a[i]); } //初始化数组第一个元素 //理解:上面只是动态初始化了整个a数组 a[0] = new int[2]; //访问第一个元素所指的第二个元素 a[0][1] = 6; for(int i = 0 , len = a[0].length; i < len ; i++) { System.out.println(a[0][i]); }}}
结果:
nullnullnullnull06
过程图:
注意:图中a[0]的元素,不能再指向另一个数组。因为Java是强类型语言,前面已经定义了数组元素是int[]类型,所以a[0]中的数组元素只能是int类型。
想实现无限扩展的数组,可以定义一个Object[]类型的数组。
//一、动态初始化另一种写法:同时初始化二维数组的两个维数int[][] b = new int[3][4];//二、静态方法来初始化,指定多个一维数组作为二维数组的初始化值String[][] str1 = new String[]{new String[3],new String[]{"Hello!"}};//更简化String[][] str2 = {new String[3],new String[]{"Hello!"}};
五、Java 8增强的工具类:Arrays
Java提供Arrays类里包含一些static修饰的方法可以直接操作数组,包含如下几个static修饰方法(通过类名调用):
- int binarySearch(type[] a,type key):用二分法查询key元素值在数组a的索引;如果不包含key
- 小白Java笔记——深入数组
- 小白Java笔记——数组
- java笔记数组小知识点
- 李刚java笔记___深入数组
- 疯狂Java笔记:4.2 深入数组
- 小白Java笔记——运行机制
- 小白Java笔记——注释
- 小白Java笔记——数据类型
- 小白Java笔记——第一个Java程序
- Java学习记录(5)——深入数组
- 【小白的java成长系列】——String类的深入分析(基于源码)
- 小白Java笔记——下载安装
- 小白Java笔记——垃圾回收机制
- 小白java笔记——UML介绍
- 小白Java笔记——标识符和关键字
- 小白Java笔记——流程控制
- java类和对象学习笔记(三)发现了一个小知识点——对象数组
- 【JAVA笔记——道】java动态代理源码深入
- ansible tower 3.2.2 安装
- Rhyme/Hibernate JTA与thread上下文的区别
- leetcode5 最长回文子串
- 使用Scrapyd部署爬虫
- Java六大设计原则
- 小白Java笔记——深入数组
- 正则表达式
- 一步一步分析讲解神经网络基础-backpropagation algorithm
- 机器学习部分书籍推荐
- 直接使用instanceclient直接连接远程oracle服务器
- android的Tcp网络通信
- 伪知识之通俗易懂得分析sklearn中的监督学习专有名词持续更新:【内向即失败--王奕君】
- ubuntu16.04+python PIL 中文标签
- 我得一天