03_数组

数组

JVM运行时数据区

分类

在这里插入图片描述

JVM栈

描述的是Java的普通方法(不带native)执行时的所占内存的内存模型。
每当Java程序执行一个方法,都会在栈上分配一块只属于该方法的内存区域,称之为栈帧,局部变量会直接存储在栈帧中。

堆(Heap)

堆是JVM内存中最大的一块,new出来的东西都在堆上。
这片空间是有内存地址的,这个内存地址是留给外界访问用的。

方法区

跟类加载相关

本地方法栈

和JVM栈相似,区别是给本地(native)方法使用的,而不是普通方法。
native方法:没有`{}``方法体,看不到实现

程序计数器(PC)

行号计数器,用来记录字节码指令执行到哪一行

引用数据类型

引用数据类型分为两部分:引用 + 对象
左边称之为引用,右边称之为对象
引用里面存的是对象的地址值

本质

指的是对象

引用数据类型和基本数据类型的区别

  1. 存储位置(本质区别)
    基本数据类型不存在引用这个概念,数据都是直接存储在栈帧里
    引用数据类型在栈帧中存储引用,引用作为一个局部变量,存储的是该引用类型在堆上对象的内存地址,存储在堆上的对象存储具体信息,才是引用数据类型的实质
  2. 打印变量名的区别
    基本数据类型,打印变量名就是该变量具体的数值
    引用数据类型,没有办法直接访问对象,打印会显示该引用存储的堆上的对象的内存地址

数组的基本操作

直接打印

打印的是该对象的一个地址值

获取数组长度

数组名.length

访问数组元素

通过下标,index
数组名[index]

修改数组元素

通过下标,index
数组名[index] = newVal

eg:
[I@1b6d3586
[:一维数组
I:int
1b6d3586:十六进制数

堆和栈中内容的区别

存储类型

堆上存储的是new出来的东西,是引用数据类型的实质——对象
栈上存储的是局部变量、基本数据类型和引用数据类型的引用

默认值

  1. 堆上对象中的变量具有默认值:
    • 整形(byte、short、int、long)默认值为0
    • 浮点类型(float、double)默认值为0.0
    • 字符类型(char)默认值是\u0000表示编码值为0的字符,一个绝对空字符。
    • 布尔类型(boolean)默认值是false
    • 引用数据类型默认值是null
  2. 栈上的局部变量没有默认值,声明局部变量后必须显式的初始化,否则无法使用。

对象中元素赋值的第一步永远是————默认初始化、具有默认值
然后才能赋其它具体值

String类型的比较

  1. 比较内容的时候用equals方法
    equals方法使用的时候注意:s1.equals(String s2),要保证s1不为null才可以
  2. ==比较的是对象地址值

生命周期

栈上局部变量跟方法同生共死
堆上对象存在,但是没有引用指向的时候,被当作了垃圾(垃圾对象),无法直接访问对象,只能通过引用间接访问;通过GC垃圾回收机制,经过一系列算法,回收掉这个垃圾

数组操作中的异常

异常的介绍

异常指的是:程序在运行期间出现了不正常情况,这种不正常情况的信息就会封装成一个异常对象。一旦程序出现异常,JVM就会终止程序执行,并在控制台打印异常信息。
异常往往都是XXXException

异常的信息

  1. 异常类型的全类名(全限定名)
  2. 出现异常的原因
  3. 出现错误的代码行(全类名、方法、行数)

异常的分类

  1. 编译时异常
  2. 运行时异常

常见的异常

  1. 数组下标越界异常(ArrayIndexOutOfBoundsException)
  2. 空指针异常(NullPointerExceptionE)
    对于空指针异常的处理,一般都是通过if进行判断进行处理

数组长度为0和数组为null以及数组未初始化的区别

  1. 数组未初始化: 这个数组完全是不可用的,没有初始化的数组毫无意义,一旦使用会编译报错。
  2. 数组长度为0:可以认为是初始化的,可以获取数组长度,不能通过下标访问元素。
  3. 数组为null:可以认为是初始化的,不可以获取数组长度,不能通过下标访问元素。

数组的常见操作

转义字符\b

数组的遍历

  1. 普通for循环
  2. JDK自带数组遍历实现
Arrays.toString(数组)

注:要传入一维数组,返回值是一个String对象
  1. 增强for循环
手写遍历
增强for循环(迭代器)

-------> 不能改变元素值 <----------

语法
for(数据类型 变量名:数组名){
	// 代码
	.....
}

语法中的各个部分:

  1. 数据类型是要遍历数组或集合中元素的数据类型。比如遍历int数组,就应该填入int
  2. 从整个遍历的过程中看来,变量名就表示数组/集合中的某一个元素。整体就代表所有元素。
快捷键

数组名.for或者`数组名.iter

增强for和普通for遍历数组时的区别
  1. 增强for的语法更简洁,并且遍历效率也会更高一点。
  2. 增强for循环中没有使用数组下标,而是直接遍历元素。当你想要在循环中使用数组下标时,就无法使用增强for了。
  3. 增强for也叫迭代器(iterator),它仅仅作为一个遍历数组/集合的工具而存在, 在增强for当中是不能修改任何元素的取值的,只能通过下标修改。

获取数组的最值

数组的逆序

  1. 使用二分法进行数组逆序
    即下标为“0”“length-1”位置的元素互换,下标为“1”“length-2”位置的元素互换…
    即,把下标为“i”“length-1-i”元素互换即可!
    只需要交换一半数组的元素即可,不要遍历整个数组,会再交换回去!
public static void reverse(int[] arr) {
    for(int x=0; x<arr.length/2; x++) {
        int temp = arr[x];
        arr[x] = arr[arr.length-1-x];
        arr[arr.length-1-x] = temp;
    }
}
  1. 使用2个标记进行逆序
public static void reverse(int[] arr) {
    for(int start=0,end=arr.length-1; start<=end; start++,end--) {
        int temp = arr[start];
        arr[start] = arr[end];
        arr[end] = temp;
    }
}

数组的拷贝

创建一个新数组,然后拷贝赋值的思路:

  1. 首先需要明确新数组的长度,初始化这个新数组。
  2. 然后遍历原先的数组,过滤掉(或者新增)一些元素,给新数组赋值。

数组的增删改查

当然“crud”指的是:

  1. ccreate:新增数据/增加。
  2. rretrieve/read:检索数据/查询。
  3. uupdate:更新数据/修改。
  4. ddelete:删除数据/删除。

数组的排序

Arrays.sort(arr);

可变长参数

参数个数是不确定的,但类型是确定的情况,Java会自动把可变参数当作数组处理

语法

权限修饰符列表 方法返回值类型 方法名(形参列表,数据类型... 变量名){
	...// 方法体
}

eg:

public static void test(int a, int... args){}

注意

注意事项:

  1. 调用方法时,如果有一个固定参数的方法匹配的同时,也可以与可变参数的方法匹配,则选择固定参数的方法。

  2. 调用方法时,如果出现两个可变参数的方法都能匹配,则报错,这两个方法都无法调用了。

    :一般来说要避免可变参数方法,发生方法重载,避免导致方法调用失效情况出现。

  3. 一个方法只能有一个可变长参数,并且这个可变长参数必须是该方法的最后一个参数

参数传递

Java的值传递

实参的copy

Java中是值传递的

Java的引用传递

实参自己

提供一个交换数组的方法swap

public static void swap(int[] arr1, int[] arr2){
	int[] temp = arr1;
	arr1 = arr2;
	arr2 = temp;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

coo1heisenberg

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

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

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

打赏作者

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

抵扣说明:

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

余额充值