嗨嗨大家~我来啦!今天我们来进入数组的学习吧。
目录
一 数组的定义
1 创建数组
2 初始化数组
二 数组的使用
1 数组的访问
2 数组的遍历
2.1 for 循环打印
2.2 for-each 打印数组
三 数组是引用类型
3.1 JVM内存分布
3.2 区分基本类型与引用类型变量
3.3 认识null
四 实际应用数组
4.1 数组作为函数参数
4.2 修改数组内容
1 直接传变量
2 传的是数组
3 传数组返回的也是数组
五 数组方法的使用
5.1 toString
5.2 copyOf
六 查找数组中的元素
6.1 顺序查找
6.2 二分查找 binarySearch
七 数组排序
7.1 冒泡排序
7.2 sort 排序方法
八 数组逆置
九 二维数组的定义
十 二维数组的打印
一 数组的定义
1 创建数组
T[] 数组名 = new T[N];
T :表示数组中存放元素的类型T[ ] :表示数组的类型N :表示数组的长度
代码示例:
int[] arr1 = new int[]{1, 2, 3}; // int[ ]为数组的类型
int[] arr2 = {1, 2, 3};
int[] arr3 = new int[10]; // 创建一个可以容纳10个int类型元素的数组
2 初始化数组
数组的初始化主要分为动态初始化和静态初始化。
- 动态初始化:在创建数组时,只定义数组中元素的个数,未给里面的元素进行赋值
例如:
int[] arr = new int[10];
- 静态初始化:在创建数组时,不定义数据元素个数,而直接将数组里的数据内容进行赋值,编译器会自己判定数组有几个元素,后面的数据必须与前面定义的数据类型一致
例如:
int[] arr = new int[]{1,2,3};
注意:静态初始化可以简写,省去后面的new int[ ],代码示例如下:
//当前代码虽然省去了new arr[],但是编译器编译代码时还是会还原
int[]arr={0,1,2,3,4,5,6,7,8,9};
静态和动态初始化也可以分为两步,但分步的第二步中new int[ ] 不能省略,代码示例如下:
//动态初始化
int[]arr1;
arr1=new int[10];
//静态初始化
int[]arr2;
arr2=new int[]{1,2,3};
类型 | 默认值 |
byte | 0 |
short | 0 |
int | 0 |
long | 0 |
float | 0.0f |
double | 0.0 |
char | /u0000 |
boolean | false |
引用 | null |
二 数组的使用
1 数组的访问
public class Test{
public static void main(String[] args){
int[] arr = {1,2,3};
System.out.println(arr[2]);
}
}
注意:数组的下标是从0开始的,所以数组用下标访问最大限度是 数组长度-1.
一旦超过访问的最大限度,实行结果便会报异常,如下示例:
public class Test {
public static void main(String[] args) {
int[] arr={1,2,3};
System.out.println(arr[3]);
}
}
2 数组的遍历
"遍历" 是指将数组中的所有元素都访问一遍, 访问是指对数组中的元素进行某种操作 ,下面我们来进行数组的打印。
2.1 for 循环打印
public class Test{
public static void main(String[] args) {
int[] arr={1,2,3};
for (int i=0;i<arr.length;i++){
System.out.println(arr[i]+"");
}
}
}
注意:在数组中可以通过数组对象.length来获取数组的长度
2.2 for-each 打印数组
语法形式:
for(元素类型t 元素变量x:遍历对象obj){
引用了x的java语句;
}
代码示例:
public class Test{
public static void main(String[] args) {
int[] arr={1,2,3};
for (int x:arr){
System.out.println(x);
}
}
}
注意:for-each 是 for 循环的另外一种使用方式, 能够更方便的完成对数组的遍历,可以避免循环条件和更新语句写错
三 数组是引用类型
3.1 JVM内存分布
我们要知道数组在内存里面的情况,就要了解Java内存分布情况,这里做必要的介绍。Java经过编译后产生的.class文件被加载到JVM虚拟机里面的本地方法栈里面运行。为了高效管理内存,JVM对内存进行了划分(JVM是一个软件,由C/C++编写的软件。这是因为系统之类的由C/C++代码编写比较高效)。
- 方法区:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据, 方法编译出的的字节码就是保存在这个区域;
- 虚拟机栈:与方法调用相关的一些信息,每个方法在执行时,都会先创建一个栈帧,栈帧中包含有:局部变量表、操作数栈、动态链接、返回地址以及其他的一些信息,保存的都是与方法执行时相关的一些信息。比如:局部变量。当方法运行结束后,栈帧就被销毁了,即栈帧中保存的数据也被销毁了;
- 本地方法栈:本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的;
- 堆:JVM所管理的最大内存区域. 使用new 创建的对象都是在堆上保存 (如前面的new int[ ] {1,2,3}) ;
- 程序计数器:只是一个很小的空间, 保存下一条执行的指令的地址。
注意:在这里我们只简单关心堆和虚拟机栈这两块空间。
3.2 区分基本类型与引用类型变量
public class Test{
public static void func() {
int a=8; //基本数据类型
int b=88; //基本数据类型
int[] arr=new int[]{1,2,3}; //引用数据类型
}
}
- 基本数据类型,就是直接创建的变量,在变量空间里存放所赋的值。在此代码实例中a、b是基本数据类型, 其对应的栈帧空间里赋值为8和88;
- 引用数据类型创建的变量,一般称为对象的引用,它在空间中存储的对象是所在空间的地址。在此代码实例中arr数组是引用类型,其内部保存的是数组在堆空间中的首地址
下面来看一个代码,分析它的输出情况
public static void func(String[] args) {
int[] arr1 = new int[3];
arr1[0] = 10;
arr1[1] = 20;
arr1[2] = 30;
int[] arr2 = new int[]{1,2,3,4,5};
arr2[0] = 100;
arr2[1] = 200;
arr1 = arr2; //此时arr1指向了arr2所指向的空间,两者指向同一个空间
arr1[2] = 300;
arr1[3] = 400;
arr2[4] = 500; //无论修改arr1或是arr2的值,都是修改同一个空间
for (int i = 0; i < arr2.length; i++) {
System.out.println(arr2[i]);
}
}
为了更好的方便大家理解,我们来画图分析:
3.3 认识null
public class Test{
public static void main(String[] args) {
int[] arr=null;
System.out.println(arr[0]);
}
}
注意: Java 中并没有约定 null 和 0 号地址的内存有任何关联.
四 实际应用数组
4.1 数组作为函数参数
数组array作为函数的参数,传递给print。
public class Test {
public static void print(int[] array){
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]+" ");
}
}
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6};
print(array);
}
}
4.2 修改数组内容
1 直接传变量
public class Test {
public static void func(int x){
x = 10;
System.out.println("x:"+x);
}
public static void main(String[] args) {
int num = 0;
func(num);
System.out.println("num:"+num);
}
}
运行结果:
在此代码中,num的值没有被修改为10,因为方法传参的时候传的是形参,形参相当于是实参的一份临时拷贝,形参的修改不会影响到实参(相当于调用方法时创建的栈帧里有一个变量的值为0,然后被修改为10,方法调用结束,创建的栈帧销毁,并无影响)
2 传的是数组
import java.util.Arrays;
public class Test {
public static void func(int[] array){
array[0] = 10;
}
public static void main(String[] args) {
int[] array = {1,2,3};
func(array);
System.out.println(Arrays.toString(array));
}
}
运行结果:
3 传数组返回的也是数组
import java.util.Arrays;
public class Test {
public static int[] func(int[] array){
array[0] = 10;
array[2] = 30;
return array;
}
public static void main(String[] args) {
int[] array = {1,2,3};
func(array);
System.out.println(Arrays.toString(array));
}
}
运行结果:
五 数组方法的使用
5.1 toString
toString方法的作用是将数组的数据变成字符串类型数据。
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] array = {1,2,3,4,5}; //定义一个数组
String arrays = Arrays.toString(array); //用字符串类型接受方法的返回值
System.out.println(arrays);
}
}
运行结果:
- 模拟实现toString
public class Test {
public static String toString(int[] array){ //返回类型为字符串类型
String array1 = "["; //定义一个字符串类型数据
for (int i = 0; i < array.length; i++) {
array1+=array[i];
if(i!= array.length-1){
array1+=",";
}
}
array1+="]";
return array1;
}
public static void main(String[] args) {
int[] array = {1,2,3,4,5}; //定义一个数组
String arrays = toString(array); //用字符串类型接收方法的返回值
System.out.println(arrays);
}
}
运行结果:
5.2 copyOf
基本用法:
public static int[] copyOf(int [] original,int newLength)
//第一个参数original:要复制的数组
//第二个参数newLength:要返回的副本长度
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] array = {1,2,3,4,5};
int[] newArray = new int[array.length]; //新数组
newArray = Arrays.copyOf(array,array.length);
System.out.println(Arrays.toString(newArray));
}
}
运行结果:
- 模拟实现copyOf
import java.util.Arrays;
public class Test {
public static int[] copyOf(int[] array,int length){
int[] newArray = new int[array.length];
for (int i = 0; i < array.length; i++) { //循环赋值
newArray[i] = array[i];
}
return newArray;
}
public static void main(String[] args) {
int[] array = {1,2,3,4,5};
int[] newArray = copyOf(array, array.length);
newArray[2] = 30; //将拷贝好的数组的第3个元素赋值为30,观察该改变是否对原数组是否有影响
System.out.println("array:"+Arrays.toString(array));
System.out.println("newArray:"+Arrays.toString(newArray));
}
}
运行结果:
六 查找数组中的元素
6.1 顺序查找
public class Test {
public static int find(int[] array,int k){
for (int i = 0; i < array.length; i++) {
if(k == array[i]){
return i;//找到了就返回下标
}
}
return -1;//找不到返回-1
}
public static void main(String[] args) {
int[] array = {1,2,3,0,7,8,9,4,5,6};
int ret = find(array,4);
System.out.println(ret);
}
}
运行结果:
6.2 二分查找 binarySearch
注意:二分查找必须是有序数组。
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7,8,9,10};
int ret = Arrays.binarySearch(array,4);
System.out.println(ret);
}
}
运行结果:
- 模拟实现 binarySearch
基本用法:
public static int binarySearch(int[] a,int key)
//a:要搜索的数组
//key:要搜索的值
public class Test {
public static int binarySearch(int[] array,int k){
int left = 0;
int right = array.length-1;
while(left<=right){
int mid = (left+right)/2;
if(array[mid]>k){ //查找范围左移
right = mid-1;
}else if(array[mid]<k){ //查找范围右移
left = mid+1;
}else{
return mid;
}
}
return -1;
}
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7,8,9,10};
int ret = binarySearch(array,4);
System.out.println(ret);
}
}
运行结果:
七 数组排序
7.1 冒泡排序
import java.util.Arrays;
public class Test {
public static void bubbleSort(int[] array){
for (int i = 0; i < array.length-1; i++) {
boolean flag = true;
for (int j = 0; j < array.length-1-i; j++) {
if(array[j]>array[j+1]){
int tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
flag = false;
}
}
if(flag == true){//已经有序
break;
}
}
}
public static void main(String[] args) {
int[] array = {1,2,3,6,5,0,4,8,7,9};
bubbleSort(array);
System.out.println(Arrays.toString(array));
}
}
运行结果:
7.2 sort 排序方法
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] array = {1,2,3,6,5,0,4,8,7,9};
Arrays.sort(array);
System.out.println(Arrays.toString(array));
}
}
运行结果:
八 数组逆置
import java.util.Arrays;
public class Test {
public static void reverse(int[] array){
int head = 0;
int tail = array.length-1;
while(head<tail){
int tmp = array[head];
array[head] = array[tail];
array[tail] = tmp;
head++;//后移
tail--;//前移
}
}
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6};
reverse(array);
System.out.println(Arrays.toString(array));
}
}
运行结果:
九 二维数组的定义
二维数组的三种定义方式:
public class Test {
public static void main(String[] args) {
int[][] array1 = {{1,2,3},{4,5,6}};
int[][] array2 = new int[2][3];
int[][] array3 = new int[][]{{1,2,3},{4,5,6}};
}
}
十 二维数组的打印
注意:Arrays包里面的toString方法是将数组中的元素转换为字符串,用2个toString方法来打印二维数组时,第一个toString已经将数组转换为字符串,第二个toString是不能接收字符串的,所以不能用toString来打印二维数组,用deepToString来打印。
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[][] array = {{1,2,3},{4,5,6}};
System.out.println(Arrays.deepToString(array));
}
}
运行结果:
注意:
- 在Java中可以省略列不能省略行;
- 在C语言中可以省略行不能省略列。
以上就是今天要分享的全部内容啦,内容比较多,大家学完记得及时复习哈~那我们下期再见啦!