Java开发基础入门--Java中数组的使用
小职 2021-11-05 来源 :「Unstoppedable」 阅读 826 评论 0

摘要:本篇主要介绍了Java开发基础入门--Java中数组的使用,通过具体的内容展现,希望对Java开发的学习有一定的帮助。

本篇主要介绍了Java开发基础入门--Java中数组的使用,通过具体的内容展现,希望对Java开发的学习有一定的帮助。

Java开发基础入门--Java中数组的使用

1.数组的基本用法

1.1一维数组的使用

1.1.1一维数组的声明和初始化

一维数组的声明

声明方式:


type var[] 或 type[] var;


例如:


int a[];

int[] a1;

double b[];

String[] c; //引用类型变量数组


Java语言中声明数组时不能指定其长度(数组中元素的数)

例如:


int a[5]; //非法


一维数组的初始化


动态初始化:

数组声明且为数组元素分配空间与赋值的操作分开进行

例如:


int[] arr = new int[3];

arr[0] = 6;

arr[1] = 1;

arr[2] = 1;

String names[];

names = new String[3];

names[0] = "钱学森";

names[1] = "邓稼先";

names[2] = "袁隆平";


静态初始化:


在定义数组的同时就为数组元素分配空间并赋值

例如:


int arr[] = new int[]{ 6, 1, 1};

//或者

int[] arr = {1,1,6};

String names[] = {"李四光","茅以升" ,"华罗庚"};


1.1.2数组元素的引用

定义并用运算符new为之分配空间后,才可以引用数组中的每个元素;


1.1.3数组元素的默认初始化值

数组是引用类型,它的元素相当于类的成员变量,因此数组一经

分配空间,其中的每个元素也被按照成员变量同样的方式被隐式

初始化。


例如:


public class Test {

    public static void main(String argv[]){

        int a[]= new int[5];

        System.out.println(a[3]); //a[3]的默认值为0

    }

}

//运行结果:

//0


注意:


对于基本数据类型而言,默认初始化值各有不同

对于引用数据类型而言,默认初始化值为null(注意与0不同!)

如下图所示:

Java开发基础入门--Java中数组的使用


1.1.4创建基本类型数组

Java中使用关键字new来创建数组

例如:


public class Test{

    public static void main(String args[]){

    int[] s;//声明

    s = new int[10];//初始化

    //也可以直接int[] s=new int[10];

    //基本数据类型数组在显式赋值之前,Java会自动给他们赋默认值。

    for ( int i=0; i<10; i++ ) {

    s[i] =2*i+1;

    System.out.println(s[i]);

    }

}



一维数组的结构图:

Java开发基础入门--Java中数组的使用

内存的简化结构

Java开发基础入门--Java中数组的使用


1.1.5初步认识Java虚拟机(JVM)

JVM 的内存被划分成了几个区域, 如图所示

Java开发基础入门--Java中数组的使用


程序计数器 (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 来调用的函数


1.2二维数组的使用

1.2.1二维数组的初始化

二维数组[][]:数组中的数组


格式1(动态初始化) :


 int[][] arr = new int[3][2];

// 定义了名称为arr的二维数组,

//二维数组中有3个一维数组

//每一个一维数组中有2个元素

//一维数组的名称分别为arr[0], arr[1], arr[2]

//给第一个一维数组1脚标位赋值为78写法是: 

arr[0][1] = 78;


格式2(动态初始化) :


 int[][] arr = new int[3][];

//二维数组中有3个一维数组。

//每个一维数组都是默认初始化值null (注意:区别于格式1)

//可以对这个三个一维数组分别进行初始化

arr[0] = new int[3];

arr[1] = new int[1];

arr[2] = new int[2];

//注:

int[][]arr = new int[][3]; //非法


格式3(静态初始化) :


 int[][] arr = new int[][]{{3,8,2},{2,7},{9,0,1,6}};

//定义一个名称为arr的二维数组,二维数组中有三个一维数组

//每一个一维数组中具体元素也都已初始化

//第一个一维数组 arr[0] = {3,8,2};

//第二个一维数组 arr[1] = {2,7};

//第三个一维数组 arr[2] = {9,0,1,6};

//第三个一维数组的长度表示方式: 

arr[2].length;


注意特殊写法情况:


int[] x,y[]; x是一维数组,y是二维数组

Java中多维数组不必都是规则矩阵形式

1.2.3二维数组的内存解析

这部分我们通过结合代码和图来理解


如下代码:

示例1:


int[][] arr = new int[3][];

arr[0] = new int[2];

arr[1] = new int[3];

arr[2] = new int[4];


其存储结构如下:

Java开发基础入门--Java中数组的使用

示例2:


int[][] arr1 = new int[4][];

arr1[1] = new int[]{1,2,3};

arr1[2] = new int[4];

arr1[2][1] = 30;


其内存结构图为:

Java开发基础入门--Java中数组的使用

示例3


int[][] arr4 = new int[3][];

System.out.println(arr4[0]);//null

System.out.println(arr4[0][0]);//报错

arr4[0] = new int[3];

arr4[0][1] = 5;

arr4[1] = new int[]{1,2};


其内存结构图为:

Java开发基础入门--Java中数组的使用


3数组中的常见操作

4.1数组转字符串

import java.util.Arrays 

int[] arr = {1,2,3,4,5,6}; 

String newArr = Arrays.toString(arr); 

System.out.println(newArr); 

// 执行结果 [1, 2, 3, 4, 5, 6]


Java 中提供了 java.util.Arrays 包, 其中包含了一些操作数组的常用方法


实现一个自己版本的 toString


public static void main(String[] args) { 

    int[] arr = {1,2,3,4,5,6};

    System.out.println(toString(arr));

    }

public static String toString(int[] arr) { 

    String ret = "[";

    for (int i = 0; i < arr.length; i++) { 

        // 借助 String += 进行拼接字符串 

        ret += arr[i]; 

        // 除了最后一个元素之外, 其他元素后面都要加上 ", " 

        if (i != arr.length - 1) {

        ret += ", ";

        } 

   }

   ret += "]"; 

   return ret; 

}


4.2数组拷贝

import java.util.Arrays 


int[] arr = {1,2,3,4,5,6}; 

int[] newArr = Arrays.copyOf(arr, arr.length);

System.out.println("newArr: " + Arrays.toString(newArr)); 

arr[0] = 10;

System.out.println("arr: " + Arrays.toString(arr)); 

System.out.println("newArr: " + Arrays.toString(newArr)); // 拷贝某个范围. 

int[] newArr = Arrays.copyOfRange(arr, 2, 4);

System.out.println("newArr2: " + Arrays.toString(newArr2));


注意事项: 相比于 newArr = arr 这样的赋值, copyOf 是将数组进行了 深拷贝, 即又创建了一个数组对象, 拷贝原有数组中的所有元素到新数组中. 因此, 修改原数组, 不会影响到新数组


深拷贝:必须将对象也拷贝一份


浅拷贝:数组内容是引用类型(地址),此时只能拷贝到地址,对象只是一个,依旧是修改同一个对象

拷贝的深浅要看拷贝对象。若为基本数据类型,则赋值就为深拷贝


实现自己版本的数组拷贝:


public static int[] copyOf(int[] arr){

    int[] ret = new int[arr.length];

    for (int i = 0; i < arr.length; i++){

        ret[i] = arr[i];

    }

    return ret;

}


4.3查找数组中的指定元素

给定一个数组, 再给定一个元素, 找出该元素在数组中的位置.


4.3.1顺序查找

public static void main(String[] args){ 

    int[] arr = {1,2,3,10,5,6}; 

    System.out.println(find(arr, 10)); 

}

public static int find(int[] arr, int toFind) {

    for (int i = 0; i < arr.length; i++) { 

        if (arr[i] == toFind) { 

        return i;

       }

     }

   return -1; // 表示没有找到 

}

// 执行结果 3


4.3.2二分查找

针对有序数组, 可以使用更高效的二分查找

以升序数组为例, 二分查找的思路是先取中间位置的元素, 看要找的值比中间元素大还是小. 如果小, 就去左边找; 否则就去右边找


public static void main(String[] args) {

    int[] arr = {1,2,3,4,5,6};

    System.out.println(binarySearch(arr, 6));

   }

public static int binarySearch(int[] arr, int toFind) {

    int left = 0;

    int right = arr.length - 1;

    while (left <= right){ 

        int mid = (left + right) / 2;//取得中间元素

        if (toFind < arr[mid]) { //去左侧区间找

        right = mid - 1; 

        } else if(toFind > arr[mid]){

        //去右侧区间找 

        left = mid + 1; 

        } else {

        // 相等, 说明找到了

        return mid;

        }

    }// 循环结束, 说明没找到

     return -1; 

 }

 // 执行结果 5


4.4数组排序(冒泡排序)

public static void main(String[] args){

    int[] arr = {9, 5, 2, 7};

    bubbleSort(arr);

    System.out.println(Arrays.toString(arr)); 

}

public static void bubbleSort(int[] arr){

    for (int i = 0; i < arr.length-1; i++){//趟数为长度-1

        boolean flg = false;//每趟都会把flg重新置为false

        for (int j=0;  j<arr.length-1-i; j++){ 

            if (arr[j - 1] > arr[j]){//检查整体是不是升序

                int tmp = arr[j - 1];//若不是,交换;若是跳过

                    arr[j - 1] = arr[j];

                    arr[j] = tmp;

                    flg = true;//交换后将flg改为true

                 } 

         }

         if(flg==false){

             break;//有序,没有交换

         }

    } // end for 

} // end bubbleSort 

// 执行结果 [2, 5, 7, 9]


冒泡排序性能较低. Java 中内置了更高效的排序算法


public static void main(String[] args){

    int[] arr = {9, 5, 2, 7}; 

    Arrays.sort(arr);//调用相应的排序算法

    System.out.println(Arrays.toString(arr));

}


4.5数组逆序

给定一个数组, 将里面的元素逆序排列.

思路:

设定两个下标, 分别指向第一个元素和最后一个元素. 交换两个位置的元素.

然后让前一个下标自增, 后一个下标自减, 循环继续即可.


这里我们以将一个升序序列逆序为例:


public static void main(String[] args){

    int[] arr = {1, 2, 3, 4};

    reverse(arr);

    System.out.println(Arrays.toString(arr)); 

   }

public static void reverse(int[] arr){ 

    int left = 0;//指向第一个元素

    int right = arr.length - 1;//指向最后一个元素

    while (left < right){//交换

        int tmp = arr[left];

        arr[left] = arr[right]; 

        arr[right] = tmp; 

        left++;

        right--; 

    }

}


4.6数组数字排列

给定一个整型数组, 将所有的偶数放在前半部分, 将所有的奇数放在数组后半部分

例如

{1, 2, 3, 4}

调整后得到

{4, 2, 3, 1}

基本思路

设定两个下标分别指向第一个元素和最后一个元素.用前一个下标从左往右找到第一个奇数, 用后一个下标从右往左找到第一个偶数, 然后交换两个位置的元素.

依次循环即可


public static void main(String[] args){

    int[] arr = {1, 2, 3, 4, 5, 6};

    transform(arr);

    System.out.println(Arrays.toString(arr));

}

public static void transform(int[] arr) { 

    int left = 0;

    int right = arr.length - 1; 

    while (left < right) {

        // 该循环结束, left 就指向了一个奇数

        while (left < right && arr[left] % 2 == 0) { 

            left++;

        }// 该循环结束, right 就指向了一个偶数 

        while (left < right && arr[right] % 2 != 0) {

            right--;

         }// 交换两个位置的元素

         int tmp = arr[left];

          arr[left] = arr[right]; 

          arr[right] = tmp; 

    }

}


4.数组使用中的常见异常

Java开发基础入门--Java中数组的使用



我是小职,记得找我

✅ 解锁高薪工作

✅ 免费获取基础课程·答疑解惑·职业测评

Java开发基础入门--Java中数组的使用

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved