Java学习 9.Java-数组 讲解及习题

一、数组的定义与使用

1.数组的基本概念

1.1 为什么要使用数组

数组是最简单的一种数据结构 组织一组相同类型数据的集合

数据结构本身是来描述和组织数据的 数据加结构

1.2.1 数组的创建

代码实现

new int 可省略;

    char[] chars={'a','b','c'};
    //定义一个整形类型数组
    int[] array={1,2,3,4,5};
    //创建数组对象
    int[] array2=new int[]{1,2,3,4,5};
    int[] array3=new int[5];//数组中的值默认初始化为0

1.2.2 数组的初始化

数组的初始化分为动态初始化和静态初始化

1.动态初始化:在创建数组时,直接指定数组中元素的个数
int[] arr = new int[10];
2.静态初始化:在创建数组时,不需要直接指定数据元素个数,而直接将具体的数据内容进行指定

语法格式:T[] 数组名 = {data1,data2,...,datan}

注意事项
数组也可以按照C语言格式创建
静态和动态初始化也可以分为两步,但是省略格式不可以

int arr[]={data1,data2,...datan}

赋值的时候必须加上new

如果没有对数组进行初始化,数组中元素有其默认值

boolean类型初始值是false

数组的初始值为0

string等引用类型的初始值为null

1.3 数组的使用

1.3.1 数组中元素的访问

数组在内存中是一块连续的空间,空间的编号是从0开始的,依次递增,该编号称为数组的下标,数组可以通过下标访问其任意位置的元素

public class day_10 {
        //通过下标访问数组元素
        int[] array={1,2,3,4,5};
        System.out.println(array[5]);//越界 数组下标超出范围,数组越界异常
    }
}
越界异常结果
Java当中的内存划分是什么样子的?JVM当中的内存划分

array叫做引用变量->引用        引用指向对象的

当数组中元素为空时,要赋值变量为null

引用变量时会发生空指针异常

求数组长度

数组名.length;        求数组长度

        //求数组长度
        System.out.println(array.length);

数组名存的是存储数据对象的地址

所以数组存放的是数据对象的地址

引用 指向 对象

array2这个引用不指向任何对象

int[] array2=null;

局部变量在使用时,一定要先进行初始化

注意事项

1.数组是一段连续的内存空间,因此支持随机访问,即通过下标访问快速访问数组中任意位置的元素

2.下标从0开始,介于(0,n)之间不包含n,n为元素个数,不能越界,否则会报出下标越界异常

1.3.2 遍历数组

方式1

数组名.length

方式2

int x:数组名

方式3 1.3.3 数组是引用类型

1.3. 3.1 初识JVM的内存分布

内存是一段连续的存储空间,主要用来存储程序运行时数据的,比如:

意义:内存很大,但是,我们如果堆内存进行一个划分之后,我们可以更好地管理内存这块区间

Java的存储细节——五个区域

1.3.4 基本类型变量与引用类型变量的区别

基本变量存储在栈上,引用变量存储在堆上

引用变量array1=array2的意义:

1.3.5 认识null 

int[] array = null;         代表array这个引用不指向任何对象

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

引用参数变量

    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};//局部变量 引用变量
        print(array);
    }
  public static void print(int[] array){
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+" ");
        }
    }

    public static void func1(int[] array){
        array=new int[]{45,63,27,9,81};
    }

    public static void func2(int[] array){
        array[0]=99;//形参当中改变了实参的值
    }

    public static void func3(int[] array){
        int tmp=array[0];
        array[0]=array[1];
        array[1]=tmp;
    }

    public static void main(String[] args) {
        int[] array={1,2,3,4};//局部变量 引用变量
        print(array);
        System.out.println();
        func1(array);
        System.out.println(array);
        func2(array);
        System.out.println(array);
        func3(array);
        System.out.println(array);
        //[I@2f7a2457
        //[I@2f7a2457
        //不是传了引用就能改变值
        //Java当中即使传递引用地址也不一定能改变实参的值
    }

1.引用变量当中存的是地址

2.引用指向变量、地址也是一种值

Java当中只有传值调用一种

传值调用改变不了形参的值

 public static void func4(int a){
        a=20;
    }        
 int x=10;
 func4(x);
 System.out.println(x);

2.作为函数的参数

1.参数传基本数据类型

因为java当中只支持传值调用,所以在方法内部修改形参不能影响实参的值

2.参数传数组类型(引用数据类型)

同样是传地址,引用数据类型传值可以修改其中存放的数据内容

 public static void func5(int a[] ){
        a[0]=99;
    }
     func5(array);
     System.out.println(array[0]);

总结

所谓的“引用“本质上只是存了一个地址,java将数组设定为引用类型,这样的话后续进行数组参数传参,其实只是将数组的地址传入搭配函数形参中,这样可以避免对整个数组的拷贝(数组如果较长,拷贝的开销就很大)

3.数组作为函数的返回值

    public static int[] func6(){
        int[] array={1,2,3,4};
        return array;
    }
        int[] y=func6();
        System.out.println(y[1]);
        System.out.println(func6());//还会打印地址

4.数组练习题

 1 获取斐波那契数列的前n项

代码实现
    public static int[] fib(int n){
        if(n<=0){
            return null;
        }
        int[] array=new int[n];
        array[0]=array[1]=1;
        for (int i = 2; i < n; i++) {
            array[i]=array[i-1]+array[i-2];
        }
        return array;
    }

    public static void main(String[] args) {
        //斐波那契数列前n项
        int[] arr=fib(10);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }
运行结果

2.将数组转变为字符串进行返回

把一个整形数组转化为字符串
@param array 数组参数
@return 将数组转变为字符串返回

代码实现
  public static String myToString(int[] array){
        if(array==null){
            return "null";
        }
        String ret="[";
        for (int i = 0; i < array.length; i++) {
            ret+=array[i];
            if(i!= array.length-1){
                ret+=",";
            }
        }
        ret+="]";
        return ret;
    }

    public static void main(String[] args) {
        int[] arr1={1,2,3,4,5,6};
        String newArr=myToString(arr1);
        System.out.println(newArr);
    }
运行结果

3.数组拷贝

赋值不是拷贝

方法一 通过Arrays进行拷贝 Arrays.copyOf字符串拷贝函数
代码实现
    public static void main(String[] args) {
        int[] arr2={1,2,3,4};
        //根据工具类直接拷贝 拷贝数组,长度为arr2.length
        int[] copy=Arrays.copyOf(arr2,arr2.length);
        //根据工具类直接拷贝 拷贝数组,长度为arr2.length*2
        //让arr指向新的空间 二倍进行扩容
        System.out.println(Arrays.toString(copy));
        copy=Arrays.copyOf(arr2,arr2.length*2);
        System.out.println(Arrays.toString(copy));
}
   
   
运行结果
方法二 通过数组名.clone进行拷贝
代码实现
    int[] copy3=arr3.clone();
    System.out.println(Arrays.toString(copy3));
运行结果

拷贝限制长度的数组

通过Arrays.copyOfRange(数组名,开始位置,结束位置)

代码实现
    public static void main(String[] args) {
        int[] arr2={1,2,3,4};
        //拷贝数组部分长度
        int[] arr3={1,2,3,4,5};
        int[] copy2=Arrays.copyOfRange(arr3,1,3);
        System.out.println(Arrays.toString(copy2));
    }
运行结果

4.求数组中元素的平均值,给定一个整形数组,求平均值

要点:记得转换为double类型 否则无法输出 方法的返回值也设置为double类型
代码实现

    public static double AVG(int[] arr){
        int sum=0;
        for(int x:arr){
            sum+=x;
        }
        return (double)sum/(double)arr.length;
    }

    public static void main(String[] args) {
        int[] arr4={1,2,3,4,5,6};
        double avg=AVG(arr4);
        System.out.println(avg);
    }
运行结果

5.查找数组中指定元素(顺序查找)

代码实现
    public static int Find(int[] arr,int data){
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]==data){
                return i;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        int arr[]={1,2,3,4,5,6,7,8,9};
        int i=Find(arr,9);
        System.out.println(i);
    }
运行结果

6.二分查找

建立在当前数组有序的情况下

思路

一直找到最中间的元素,查询元素与最中间的元素比大小,如果小则让左区间加一,如果大则让右区间-1,重复查询左区间和右区间和的二分之一,所以只适用于当前数组元素有序的情况下,如果查询不到则返回负的当前数组长度+1的值

代码实现
    public static int ErFind(int[] arr,int key){
        int i=0;
        int j= arr.length-1;
        while (i<=j){
            int mid=(i+j)/2;
            if(arr[mid]<key){
                i=mid+1;
            } else if (arr[mid]==key) {
                return mid;
            }else {
                j=mid-1;
            }
        }
        return -1 ;
    }

    public static void main(String[] args) {
        int[] array={1,2,31,14,5,8};
        //数组排序
        Arrays.sort(array);
        System.out.println(Arrays.toString(array));
        System.out.println(Arrays.binarySearch(array,51));
        System.out.println(Arrays.binarySearch(array,31));
    }
运行结果

7.数组元素逆序

思路

while循环进行两元素的交换,传值调用进行交换

代码实现
    //习题7 数组元素逆序
    public static void reverse(int[] array){
        int i=0;
        int j= array.length-1;
        while(i<j){
            int t=array[i];
            array[i]=array[j];
            array[j]=t;
            i++;
            j--;
         }
    }

    public static void main(String[] args) {
        int[] array ={1,2,3,4,5};
        reverse(array);
        System.out.println(Arrays.toString(array));;
    }
运行结果

8.通过函数比较两数组值是否一样

Arrays.equals(数组名1,数组名2);

代码实现
    public static void main(String[] args) {
        int[] array1 = {1,2,3,14,5,6};
        int[] array2 = {1,2,3,4,5,6};
        System.out.println(Arrays.equals(array1, array2));
        reverse(array1);
        System.out.println(Arrays.toString(array1));
        System.out.println(Arrays.equals(array1, array2));
    }
运行结果

9.局部填充部分数组

Arrays.fill函数

代码实现
    public static void main(String[] args) {
        int[] array=new int[10];
        Arrays.fill(array,1,3,99);//左闭右开
        System.out.println(Arrays.toString(array));
    }
运行结果

10.冒泡排序

思路

两重for循环,为避免排序成功后继续遍历,加入一个boolean类型的变量,最终排序成功后进行输出

代码实现
    public static void main(String[] args) {
        int[] arr={8,12,9,10,6};
        //i比较的是趟数
        for (int i = 0; i < arr.length-1; i++) {
            //避免以及排序正确后还要继续排序
            boolean flg=false;
            for (int j = 0; j < arr.length-i-1; j++) {
                if (arr[j] >= arr[j+1]) {
                    int t=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=t;
                    flg=true;
                }
            }
            //避免排序后还要继续排序
            if(flg==false){
                return;
            }
        }
        System.out.println(Arrays.toString(arr));
    }
运行结果

二、二维数组

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

基本语法

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

    int[][] array={{1,2,3},{4,5,6}};
    int[][] array2=new int [5][4];//默认初始化为0
    int[][] array3=new int[][]{{1,2,3},{4,5,6}};

二维数组是一个特殊的一维数组

二维数组的存储形式

二维数组可以省略行,可以省略列,C语言可以省略行员,Java可以省略列

三种定义方式

    int[][] array = {{1, 2, 3}, {4, 5, 6}};
   //二维数组可以省略行,可以省略列,C语言可以省略行员,Java可以省略列
    int[][] array2 = new int[5][4];//默认初始化为0
    int[][] array3 = new int[][]{{1, 2, 3}, {4, 5, 6, 7}};

不规则的二维数组

        array4[0]=new int[2];
        array4[1]=new int[2];
        array4[2]=new int[5];
数组名.length求数组列数
数组名[列数].length 求数组列数

两层for循环,遍历二维数组

        for (int i = 0; i < array4.length; i++) {
            for (int j = 0; j < array4[i].length; j++) {
                System.out.print(array4[i][j] + " ");
            }
            System.out.println();
        }

for each遍历

代码实现
        //for each遍历
        for (int[] tmpArray : array) {
            System.out.println(tmpArray);
            for (int x : tmpArray) {
                System.out.print(x + " ");
            }
            System.out.println();
        }
        //打印二维数组
        String ret= Arrays.deepToString(array);
        System.out.println(ret);
运行结果

Arrays函数打印二维数组

语法

Arrays.deepToString(数组名);

代码实现
        //打印二维数组
        String ret= Arrays.deepToString(array);
        System.out.println(ret);
运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/133227.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在线免费语音克隆工具,1分钟,复制你的声音

hi&#xff0c;同学们&#xff0c;我是赤辰。玩自媒体这么多年&#xff0c;总结出凡是用自己的声音做短视频&#xff0c;既有识别度&#xff0c;也更容易上热门&#xff0c;但是录制音频的艰难&#xff0c;试过的都知道&#xff0c;市面上也有很多克隆工具&#xff0c;但是基本…

【Git】Git分支与标签掌握这些技巧让你成为合格的码农

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Git》。&#x1f3af;&#x1f3af; &#x1f449…

Qt——连接mysql增删查改(仓库管理极简版)

目录 UI布局设计 .pro文件 mainwindow.h main.cpp UI布局设计 .pro文件 QT core gui QT core gui sql QT sqlgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any …

【算法-链表4】环形链表2的两种解法

今天&#xff0c;带来链表相关算法的讲解。文中不足错漏之处望请斧正&#xff01; 理论基础点这里 环形链表 1. 思路 利用链表相交 我们在环内任意一处断开&#xff0c;然后判断断开处的下一个位置和head是否相交&#xff0c;如果相交&#xff0c;相交处就是环口。 公式法 …

ArcGIS10.8 连接 PostgreSQL 及遇到的两个问题

前提 以前同事用过我的电脑连PostgreSQL&#xff0c;失败了。当时不知道原因&#xff0c;只能使用GeoServer来发布数据了。现在终于搞明白了&#xff0c;原因是ArcGIS10.2版本太老&#xff0c;无法连接PostgreSQL9.4。参考这里 为了适应时代的发展&#xff0c;那我就用新的Ar…

Spark的转换算子和操作算子

1 Transformation转换算子 1.1 Value类型 1&#xff09;创建包名&#xff1a;com.shangjack.value 1.1.1 map()映射 参数f是一个函数可以写作匿名子类&#xff0c;它可以接收一个参数。当某个RDD执行map方法时&#xff0c;会遍历该RDD中的每一个数据项&#xff0c;并依次应用f函…

python Flask框架,调用MobileNetV2图像分类模型,实现前端上传图像分类

python Flask框架&#xff0c;调用MobileNetV2图像分类模型&#xff0c;实现前端上传图像分类 今天博主介绍一个图像分类的小项目 基于flask 和mobileNetV2模型的前端图像分类项目 环境配置如下&#xff1a; python版本3.7.6 安装库的版本如下&#xff1a; tensorflow 2.11.…

LabVIEW中NIGPIB设备与驱动程序不相关的MAX报错

LabVIEW中NIGPIB设备与驱动程序不相关的MAX报错 当插入GPIB-USB设备时&#xff0c;看到了NI MAX中列出该设备&#xff0c;但却显示了黄色警告指示&#xff0c;并且指出Windows没有与您的设备相关的驱动程序。 解决方案 需要安装能兼容的NI-488.2驱动程序。 通过交叉参考以下有…

STM32--时钟树

一、什么是时钟&#xff1f; 时钟是单片机的脉搏&#xff0c;是系统工作的同步节拍。单片机上至CPU&#xff0c;下至总线外设&#xff0c;它们工作时序的配合&#xff0c;都需要一个同步的时钟信号来统一指挥。时钟信号是周期性的脉冲信号。 二、什么是时钟树&#xff1f; S…

“Git实践指南:深入探索开发测试上线、分支管理与标签“

文章目录 引言一、Git的分支的使用1.分支2.标签3.分支与标签的关系4. 分支在实际中的作用5. 四个环境以及各自的功能特点6. 分支策略分支应用场景 二、Git的标签3.1 标签的基本使用3.3 标签的共享与推送 总结 引言 在现代软件开发中&#xff0c;版本控制是一个关键的环节&…

2023年【危险化学品经营单位主要负责人】免费试题及危险化学品经营单位主要负责人证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年危险化学品经营单位主要负责人免费试题为正在备考危险化学品经营单位主要负责人操作证的学员准备的理论考试专题&#xff0c;每个月更新的危险化学品经营单位主要负责人证考试祝您顺利通过危险化学品经营单位主…

【扩散模型】万字长文全面理解与应用Stable Diffusion

万字长文全面理解与应用Stable Diffusion 1. Stable Diffusion简介1.1 基本概念1.2 主体结构1.3 训练细节1.4 模型评测1.5 模型应用1.6 模型版本1.7 其他类型的条件生成模型1.8 使用DreamBooth进行微调 2. 实战Stable Diffusion2.1 环境准备2.2 从文本生成图像2.3 Stable Diffu…

LIBGDX实时绘制字符、实时绘制中文

LIBGDX实时绘制字符、实时绘制中文 转自&#xff1a;https://lingkang.top/archives/libgdx-shi-shi-hui-zhi-zi-fu 注意&#xff0c;相比于贴图字体&#xff0c;实时绘制会有一定的失真、模糊 Maven项目依赖&#xff1a; <properties><maven.compiler.source>…

抢量双11!抖音商城「官方立减」 缘何成为“爆单神器”?

10月20日抖音商城双11好物节正式开跑&#xff0c;仅仅三天&#xff0c;抖音商城整体GMV对比去年同期提升了200%&#xff0c;而在开跑一周后&#xff0c;一些品牌的销售额已经超过了今年整个618&#xff0c;可谓增势迅猛。其中&#xff0c;平台官方特别推出的「官方立减」玩法&a…

基于51单片机的篮球比赛计分器积分器

wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;单片机篮球 获取完整源程序仿真源文件原理图文件论文报告等 基于51单片机的篮球计分器 由STC89C51单片机数码管显示模块按键模块电源模块构成 具体功能&#xff1a; &#xff08;1&#xff09;能记录单节比赛的比赛时间&am…

ETW HOOK原理探析

ETW HOOK研究 文章目录 ETW HOOK研究前言原理探究内核开启ETW日志HOOK ETW修改ETW日志上下文代理GetCpuClock函数寻找SSDT和SSDT Shadow 总结参考 前言 关于ETW是什么我就不多说了&#xff0c;可以通过微软的相关文档了解到。据网上得知这项技术最早被披露于2345的驱动中&…

【字符串】【双指针翻转字符串+快慢指针】Leetcode 151 反转字符串中单词【好】

【字符串】【双指针翻转字符串快慢指针】Leetcode 151 反转字符串中单词 解法1 双指针翻转字符串快慢指针更新数组大小 ---------------&#x1f388;&#x1f388;题目链接&#x1f388;&#x1f388;------------------- ---------------&#x1f388;&#x1f388;解答链接…

UI自动化测试 | Jenkins配置优化

前一段时间帮助团队搭建了UI自动化环境&#xff0c;这里将Jenkins环境的一些配置分享给大家。 背景&#xff1a; 团队下半年的目标之一是实现自动化测试&#xff0c;这里要吐槽一下&#xff0c;之前开发的测试平台了&#xff0c;最初的目的是用来做接口自动化测试和性能测试&…

MySQL 数据库查询与数据操作:使用 ORDER BY 排序和 DELETE 删除记录

使用 ORDER BY 进行排序 使用 ORDER BY 语句按升序或降序对结果进行排序。 ORDER BY 关键字默认按升序排序。要按降序排序结果&#xff0c;使用 DESC 关键字。 示例按名称按字母顺序排序结果&#xff1a; import mysql.connectormydb mysql.connector.connect(host"l…

Linux 内核定时器

一个人总要走陌生的路&#xff0c;看陌生的风景&#xff0c;听陌生的歌&#xff0c;然后在某个不经意的瞬间&#xff0c;你会发现&#xff0c;原本费尽心机想要忘记的事情真的就这么忘记了。 ----小新 一、引言 Linux内核定时器是一种用于在特定时间间隔后触发特定事件的重要组…