【Java】浅谈Java数组的定义与使用

简介: 【Java】浅谈Java数组的定义与使用

image.png

💜写在前边💜

前言

本篇博客主要讲述了以下几点问题


1. 理解数组基本概念

2. 掌握数组的基本用法

3. 数组与方法互操作

4. 熟练掌握数组相关的常见问题和代码~


【☕Java】浅谈Java数组的定义与使用

💜写在前边💜

🎄数组基本用法

🎅什么是数组

🎅创建数组

🎅数组的使用

🎄数组作为方法的参数

🎅基本用法

🎅理解引用类型(敲黑板!!!)

🎅认识null

🎅 初时JVM内存区域划分(敲黑板!!!)

🎅数组作为方法的返回值

🎄数组练习

🎅二分查找

🎅冒泡排序

🎅判断数组是否有序

🎅只出现一次的元素

🎅改变原有数组的值

🎅数组所以元素之和

🎅 数组拷贝

🎅数组转字符串

🎅求数组元素平均值

🎄二维数组

🎄数组基本用法

🎅什么是数组

【数组】本质上就是让我们能 “批量” 创建相同类型的变量.


例如:

如果需要表示两个数据, 那么直接创建两个变量即可 int a; int b

如果需要表示五个数据, 那么可以创建五个变量 int a1; int a2; int a3; int a4; int a5;

但是如果需要表示一万个数据, 那么就不能创建一万个变量了. 这时候就需要使用数组, 帮我们批量创建.


注意事项: 在 Java 中, 数组中包含的变量必须是 相同类型.


🎅创建数组

基本语法


动态初始化

数据类型[] 数组名称 = new 数据类型 [ ] { 初始化数据 };


如果在创建的同时不初始化数组则必须指定其大小

数据类型[] 数组名称 = new 数据类型 [元素个数] ;


静态初始化

数据类型[] 数组名称 = { 初始化数据 };

image.png

image.png

🎅数组的使用

image.png

注意事项

1. 使用 arr.length 能够获取到数组的长度【. 】这个操作为成员访问操作符. 后面在面向对象中会经常用到.

2. 使用 [ ] 按下标取数组元素. 需要注意, 下标从 0 开始计数

3. 使用 [ ] 操作既能读取数据, 也能修改数据.

4. 下标访问操作不能超出有效范围 [0, length - 1] , 如果超出有效范围, 会出现下标越界异常

image.png

image.png

image.png

🎄数组作为方法的参数

🎅基本用法


image.png

🎅理解引用类型(敲黑板!!!)

我们知道Java是一门纯面向对象的语言,我们在使用Java语言编程时,到处都在使用对象(《Thinking in Java》一书中提到"Everything is object")

程序在运行时,对象是在堆内存(heap)中存储的,那么我们如何来访问对象呢?在C/C++中是通过指针,而Java中是通过引用,引用储存了对象在堆内存(heap)中的地址。


这里我们要先从内存开始说起.

如何理解内存?

内存就是指我们熟悉的 “内存”. 内存可以直观的理解成一个宿舍楼. 有一个长长的大走廊, 上面有很多房间.每个房间的大小是 1 Byte (如果计算机有 8G 内存, 则相当于有 80亿 个这样的房间).

每个房间上面又有一个门牌号, 这个门牌号就称为 地址

那么啥又是引用?

什么是引用?

引用相当于一个 “别名”, 也可以理解成一个指针.

创建一个引用只是相当于创建了一个很小的变量, 这个变量保存了一个整数, 这个整数表示内存中的一个地址.

image.png

引用与指针区别

(1)类型:

引用其值为地址的数据元素,Java封装了的地址,可以转换成字符串查看,长度也可以不必担心。

C指针是一个装地址的变量,长度一般是计算机字长,可以认为是个int。

(2)所占内存:

引用声明时没有实体,不占空间。

C指针如果声明之后会用到才会赋值。如果用不到不会分配内存。

(3)类型转换:

引用的类型转换,也可能不成功,运行时抛异常或者编译就不能通过。

C指针指示个内存地址,指向内存,对程序来说还都是一个地址,但可能所指的地址不是程序想要的。

(4)初始值:

引用初始值为java关键字null。

C指针是int,如不初始化指针,那它的值就不是固定的了,这很危险。

(5)计算:

引用不可以计算。

C指针是int,他可以计算,如++或–,所以经常用指针来代替数组下标。

(6)内存泄露:

Java引用不会产生内存泄露。

C指针是很容易产生内存泄露的,所以程序员要小心使用,及时回收。


🎅认识null

null 在 Java 中表示 “空引用” , 也就是一个无效的引用.

null 的作用类似于 C 语言中的 NULL (空指针), 都是表示一个无效的内存位置. 因此不能对这个内存进行任何读写操作. 一旦尝试读写, 就会抛出 NullPointerException.


注意: Java 中并没有约定 null 和 0 号地址的内存有任何关联.


🎅 初时JVM内存区域划分(敲黑板!!!)

image.png

程序计数器 (PC Register): 只是一个很小的空间, 保存下一条执行的指令的地址.

虚拟机栈(JVM Stack): 重点是存储局部变量表(当然也有其他信息). 我们刚才创建的 int[] arr 这样的存储地址的引用就是在这里保存.

本地方法栈(Native Method Stack): 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的.

堆(Heap): JVM所管理的最大内存区域. 使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2, 3} )

方法区(Method Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据. 方法编译出的的字节码就是保存在这个区域.

运行时常量池(Runtime Constant Pool): 是方法区的一部分, 存放字面量(字符串常量)与符号引用. (注意 从 JDK1.7 开始, 运行时常量池在堆上).

Native 本地方法:

JVM 是一个基于 C++ 实现的程序. 在 Java 程序执行过程中, 本质上也需要调用 C++ 提供的一些函数进行和操作系统底层进行一些交互. 因此在 Java 开发中也会调用到一些 C++ 实现的函数.

这里的 Native 方法就是指这些 C++ 实现的, 再由 Java 来调用的函数.


我们发现, 在上面的图中, 程序计数器, 虚拟机栈, 本地方法栈被很多个基佬紫的, 名叫 Thread(线程) 的方框圈起来了,并且存在很多份. 而 堆, 方法区, 运行时常量池, 只有一份.


重点理解 虚拟机栈 和 堆.

image.png

  • 局部变量和引用保存在栈上, new 出的对象保存在堆上.
  • 堆的空间非常大, 栈的空间比较小.
  • 堆是整个 JVM 共享一个, 而栈每个线程具有一份(一个 Java 程序中可能存在多个栈).

🎅数组作为方法的返回值


image.png

image.png

这样的话就不会破坏原有数组了.
另外由于数组是引用类型, 返回的时候只是将这个数组的首地址返回给函数调用者, 没有拷贝数组内容, 从而比较高效.

🎄数组练习

🎅二分查找


image.png

🎅冒泡排序

image.png

🎅判断数组是否有序

image.png

🎅只出现一次的元素

public class 只出现一次的数字 {
    public static int Only(int arr[]) {
         int tmp = 0;
         for (int i = 0; i < arr.length; i++) {
             /*
                涉及到异或运算,对于这道题,你应该了解异或有什么样性质
                1. 任何数与0异或,都为原数
                2. 与本身自己异或,则为0
                3. 交换律和结合律(解决这道题的关键),你把整个循环的计算写成数学运算过程,你会发现要利用交换律和结合律,可以实现这道题的要求
                 */
             tmp ^= arr[i];
         }
         return tmp;
    }
    public static void main(String[] args) {
        int arr[] = {2,0,0,1,1,2,6};
        System.out.println(Only(arr));
    }
}

🎅改变原有数组的值

image.png

🎅数组所以元素之和


image.png

🎅 数组拷贝

image.png

🎅数组转字符串

image.png

🎅求数组元素平均值

image.png

🎄二维数组

二维数组本质上也就是一维数组, 只不过每个元素又是一个一维数组.


image.png

image.png







相关文章
|
17天前
|
Java 编译器
Java重复定义变量详解
这段对话讨论了Java中变量作用域和重复定义的问题。学生提问为何不能重复定义变量导致编译错误,老师通过多个示例解释了编译器如何区分不同作用域内的变量,包括局部变量、成员变量和静态变量,并说明了使用`this`关键字和类名来区分变量的方法。最终,学生理解了编译器在逻辑层面检查变量定义的问题。
Java重复定义变量详解
|
26天前
|
存储 缓存 算法
Java 数组
【10月更文挑战第19天】Java 数组是一种非常实用的数据结构,它为我们提供了一种简单而有效的方式来存储和管理数据。通过合理地使用数组,我们能够提高程序的运行效率和代码的可读性。更加深入地了解和掌握 Java 数组的特性和应用,为我们的编程之旅增添更多的精彩。
31 4
|
26天前
|
存储 缓存 算法
提高 Java 数组性能的方法
【10月更文挑战第19天】深入探讨了提高 Java 数组性能的多种方法。通过合理运用这些策略,我们可以在处理数组时获得更好的性能表现,提升程序的运行效率。
22 2
|
1月前
|
存储 Java
Java“(array) <X> Not Initialized” (数组未初始化)错误解决
在Java中,遇到“(array) &lt;X&gt; Not Initialized”(数组未初始化)错误时,表示数组变量已被声明但尚未初始化。解决方法是在使用数组之前,通过指定数组的大小和类型来初始化数组,例如:`int[] arr = new int[5];` 或 `String[] strArr = new String[10];`。
|
1月前
|
Oracle Java 关系型数据库
重新定义 Java 对象相等性
本文探讨了Java中的对象相等性问题,包括自反性、对称性、传递性和一致性等原则,并通过LaptopCharger类的例子展示了引用相等与内容相等的区别。文章还介绍了如何通过重写`equals`方法和使用`Comparator`接口来实现更复杂的相等度量,以满足特定的业务需求。
21 3
|
1月前
|
存储 Java
什么是带有示例的 Java 中的交错数组?
什么是带有示例的 Java 中的交错数组?
44 9
|
1月前
|
存储 Java 编译器
Java集合定义其泛型
Java集合定义其泛型
18 1
|
1月前
|
Java
Java数组动态扩容和动态缩减
Java数组动态扩容和动态缩减
22 3
|
1月前
|
存储 Java 程序员
【一步一步了解Java系列】:何为数组,何为引用类型
【一步一步了解Java系列】:何为数组,何为引用类型
23 1
|
1月前
|
存储 XML Java
如何在 Java 中将常见文档转换为 PNG 图像数组
如何在 Java 中将常见文档转换为 PNG 图像数组
14 1