当前位置: 首页 > article >正文

JAVA系列之数组的秘密(数组的一般用法+力扣 斯坦福大学练习精解)

大佬们好呀~
更多精彩: 个人主页
JAVA专栏

在这里插入图片描述

文章目录

  • 一、数组的概述
    • 1.1什么是数组?
    • 1.2注意:
    • 1.3建议:
  • 二、数组的定义
    • 1.格式:
  • 三、数组的静态初始化
    • 1.数组的初始化:
    • 2.静态初始化:
      • 格式:
      • 数组的长度:
  • 四、数组的地址值
    • 1.1地址值:
    • 1.2拓展:
  • 五、数组的元素访问
    • 1.格式:
    • 2.索引:
    • 3.获取数组中的元素
    • 4.把数据存入到数组中
  • 六、数组的遍历
    • 1.数组的遍历:
    • 2.拓展:
    • 3.练习:
      • 3.1遍历数组求和
      • 3.2条件变化
  • 七、数组的动态初始化
    • 1.动态初始化:
      • 1.1信息存入:
        • 1.1.1添加:
        • 1.1.2获取:
      • 1.2数组默认初始化值的规律
    • 2.动态初始化与静态初始化的区别
  • 八、数组的常见问题
  • 九、数组的常用操作
    • 1.求最值
    • 2.遍历求和
    • 3.交换数据
    • 4.打乱数据
  • 十、数组的内存图
    • 1.java的内存分配
    • 2.数据的内存图

前言
在 Java 编程中,我们经常要处理一系列数据,数组作为最基础、常用的数据结构,就像有序容器,能有效存储和管理数据。接下来,让我们深入探索 Java 数组,从基础到高级,掌握这一关键知识,助力 Java 编程。

一、数组的概述

1.1什么是数组?

数组指的是一种容器,可以用来存储同种数据类型的多个值。

1.2注意:

这里在存储数据的时候要注意隐式转换。

int 类型的容器可存储(byte,short,intdouble 类型的数组容器可储存(byte,short,int,long,float,double)
    
(大)double>float>long>int>short>byte(小)
    
 大可以储存小(隐式转换),小不可以储存大!(强制转换)

1.3建议:

容器的类型和存储的数据类型保持一致~!

二、数组的定义

1.格式:

格式:
    
数据类型 [] 数组名 或 数据类型 数组名 []
    
int [] arry 或 int arry []

[]此符号代表定义的是一个数组,不写代表定义的是一个变量

三、数组的静态初始化

1.数组的初始化:

初始化:就是在内存中,为数组容器开辟空间,并将数组存入容器中的过程。

包括:静态初始化和动态初始化

2.静态初始化:

数组的内容是固定的已知的。

格式:

完整格式:
    
数据类型 [] 数组名 = new 数据类型[]{元素1,元素2,元素3......};
int [] nums = new int [] {1,2,3,4,5};

简化格式:

数据类型[] 数组名={元素1,元素2};
int arry []={123};

数组的长度:

arry : 长度为3

112233

四、数组的地址值

当我们定义一个数组,其中含有三个元素(1,2,3),打印出这个数组arry.

eg:
int arry []={1,2,3};
System.out.println(arry);

运行展示:

[I@10f87f48

运行出来会出现一段乱码,当然乱码并不是真的乱码,而是数组的地址值

1.1地址值:

就是表示数组在内存中的位置。

1.2拓展:

解释一下地址值的格式含义:

[:表示当前是一个数组

I:表示当前数组里面的元素是int类型的

@:表示一个间隔符号(固定格式)

10f87f48:这才是数组真正的地址值(十六进制)

平时我们习惯性的会把这个整体叫做数组的地址值

五、数组的元素访问

1.格式:

数组名[索引];
eg:
nums[0];

2.索引:

数值1234
索引(下标)0123

特点:从0开始,逐个+1增长,连续不断

3.获取数组中的元素

int [] arr={11,12,13};
int num=arr[0];
System.out.println(num);

简单写法:
int [] arr={11,12,13};
System.out.println(arr[0]);
run:
11

4.把数据存入到数组中

格式:
数组名[索引]=具体数据/变量
    
arr[0]=100
public class boke {
    public static void main(String[] args) {
        int [] arr={11,12,13};
       arr[0]=100;
        System.out.println(arr[0]);
    }
}

run:
100

细节:一旦覆盖之后,原来的数据就不存在了

六、数组的遍历

1.数组的遍历:

将数组中所有的内容取出来,取出来之后(打印,求和,判断)

注:遍历指的是取出数据的过程不要局限的理解为遍历就是打印

根据我们上文的学习,大家可能会想,我一个个使用arr[i]打印出来不行吗?

public class boke{
    public static void main(String[]args){
        int [] arr={1,2,3,4,5};
        System.out.println(arr[0]);
        System.out.println(arr[1]);
        System.out.println(arr[2]);
        System.out.println(arr[3]);
        System.out.println(arr[4]);
       
    }
}
run:
1
2
3
4
5

虽然这样一个一个println也可以遍历出数组的数据,可是当数组的数据个数足够庞大时我们应该怎么办呢?

我们想到了循环:将索引换成变量i,然后再循环打印arr[i]

我们来做一下代码实现:

int [] arr={11,12,13};
for (i=0;i<=4;i++){
    System.out.println(arr[i]);
}

我们在写循环时可能会遇到数组长度的问题,我们有一个官方写法:

调用方式:
数组名.length
System.out.println(arr.length);
//打印数组的长度

2.拓展:

自动的快速生成数组的遍历方式

由IDEA提供的,数组名.fori回车,就会出现以下代码。

for (int i=0;i<arr.length;i++){
    System.out.println(arr[i]);
}

3.练习:

3.1遍历数组求和

//将数组中的11,22,33,44,55,66,77,88,99求和
public class bianli{
    public static void main (String[]args){
        int [] num ={11,22,33,44,55,66,77,88,99};
        int sum = 0;
        for (int i=0 ; i<num.length ; i++){
            sum+=num[i];
        }
        System.out.println(sum);
    }
}

3.2条件变化

//如果是奇数,将当前数字扩大两倍,偶数将当前数字变成1/2
int [] num={1,2,3,4,5,6,7,8,9,10};
for (i=0 ; i<num.length ; i++){
    if (num[i]%2==0){
        num[i]/=2;
    }else{
        num[i]*=2;
    }
    System.out.println(num[i]);
}

一般情况下,一个循环只做一件事,于是我们可以优化一下

int [] num={1,2,3,4,5,6,7,8,9,10};
for (i=0 ; i<num.length ; i++){
    if (num[i]%2==0){
        num[i]/=2;
    }else{
        num[i]*=2;
    }
}
for (i=0 ; i<num.length ; i++){
    System.out.println(num[i]);
}//重新遍历一下

七、数组的动态初始化

1.动态初始化:

初始化时只指定数组长度,由系统为数组分配初始值。

格式:
数据类型[]数组名=new 数组类型[数组长度];
int [] arr = new int [3];
//先建立一个空壳,[3]说明只能存3个int类型的整数

在创建的时候,有我们自己指定数组的长度,由虚拟机给出默认的初始值。

1.1信息存入:

1.1.1添加:
arr[0]=3;
1.1.2获取:
System.out.println(arr[1]);

run:0(默认初始化值)

1.2数组默认初始化值的规律

整数类型:默认初始化值0
小数类型:默认初始化值0.0
字符类型:默认初始化值‘/u0000’空格
布尔类型:默认初始化值false
引用数据类型:默认初始化值null

2.动态初始化与静态初始化的区别

动态:

含义:手动指定数组的长度,由系统给出默认初始化值

只明确元素的个数,不明确具体数值,推荐使用动态初始化

eg:

使用数组容器来存储键盘录入的5个整数

int [] arr = {????};
int [] arr = new int[5]

静态

含义:手动指定数组元素,系统会根据元素个数,计算出数组的长度。

需求中已经明确了要操作的具体数据,直接静态初始化即可。

eg:

将全班 的学生成绩存入数组中11,22,33

int [] nums= {11,22,33};

八、数组的常见问题

索引越界异常:访问了不存在的索引

索引的范围:0~数组的长度-1

九、数组的常用操作

1.求最值

//已知数组元素为{33,5,22,44,55},请找出数组中最大的值并打印在控制台。
public class wenti {
    public static void main(String[] args) {
        int [] best ={33,5,22,44,55};
        int max = best[0];//记录数值的变化
        for (int i = 0; i < best.length; i++) {
            //遍历数组中的每一个元素,让他和max比较,如果找到更大的就记录
            if (best[i]>max) {
                max = best[i];
            }
        }
        System.out.println(max);
    }
}

2.遍历求和

//生成10个1-100之间的随机数存入数组
//求出所有数据的和
//求出所有数据的平均数
//统计有多少个数据比平均数小
import java.util.Random;
public class suym {
    public static void main(String[] args) {
        Random rand = new Random();
        int [] num  = new int[10];
        int sum = 0;
        int count = 0;
        for (int i = 0; i < 10; i++) {
            int x = rand.nextInt(100)+1;
            num[i] = x;
            sum += x;
            System.out.println(x);
            if (num[i] < sum/10){
                count++;
            }
        }
        System.out.println("生成随机数的和为:"+sum);
        System.out.println("生成随机数的平均数为:"+sum/10);
        System.out.println("小于平均数的个数为:"+count);
    }
}
 

3.交换数据

//将数组{1,2,3,4,5}顺序交换
public class jiaoone {
    public static void main(String[] args) {
        int [] arr={1,2,3,4,5};
        //从两头开始遍历,然后交换
        for(int i=0 , j=arr.length-1 ; i<j ; i++,j--){
            //找一个工具人,方便交换
            int temp=arr[i];
            arr[i]=arr[j];
            arr[j]=temp;
        }
        for (int i = 0; i < arr.length; i++) {
            //print同行打印
            System.out.print(arr[i]+" ");
        }
    }
}

4.打乱数据

//需求:将数组打乱
import java.util.Random;
public class da {
    public static void main(String[] args) {
        //导入随机数
        Random ran=new Random();
        int random=ran.nextInt(nums.length);
        int [] nums={1,2,3,4,5};
        for (int i = 0; i < nums.length; i++) {
            //遍历数组拿着它和随机索引交换
            int temp=nums[i];
            nums[i]=nums[random];
            nums[random]=temp;
        }
        for (int i = 0; i < nums.length; i++) {
            System.out.print(nums[i]+" ");
        }
    }

}

十、数组的内存图

1.java的内存分配

在这里插入图片描述

注:从JDK8开始,取消方法区,新增原空间,把原来方法区的多种功能拆分,有的功能放到了推中,有的功能放到了元空间中。

在这里插入图片描述

:方法运行时使用的内存,比如main方法运行进入方法栈中执行。

:存储对象或者数组,new来创建的,都存在堆内存

方法区:存储可以运行的class文件

本地方法栈:JVM在使用操作系统功能的时候,和我们开发无关。

寄存器:给CPU使用,和我们开发无关

在这里插入图片描述
在这里插入图片描述

2.数据的内存图

通过arr找到地址值,再通过索引找到数组内容。

注:

1.只要是new出来的一定是在推里面开辟了一个小空间

2.如果new了多次,那么在堆里面有多个小空间,每个小空间中都有各自的数据。
在这里插入图片描述

两个数组指向同一个空间的内存图:

注:当两个数组指向同一个小空间时,其中一个数组对小空间中的值发生了改变,那么其他数组再次访问的时候都是修改之后的结果了。

在这里插入图片描述
在这里插入图片描述


http://www.kler.cn/a/551691.html

相关文章:

  • Ansible自动化运维中剧本角色(roles)来完成apache服务操作
  • 如何在本地和线上安装和配置RabbitMQ
  • 交换机三层转发原理(涵盖ARP,ICMP,IP协议)
  • 探秘 Python 枚举类型:从基础到实战的深度指南
  • pyqt写一个待办程序
  • IIS asp.net权限不足
  • Android Studio:用handler实现计数
  • 基于遗传算法排课系统
  • Flutter 3.29.0 新特性 CupertinoNavigationBar 可配置bottom属性
  • AI(人工智能)会给嵌入式领域带来哪些机遇与挑战?
  • golang常用库之-swaggo/swag根据注释生成接口文档
  • 电磁铁在生产与生活中的广泛应用
  • Ubuntu 24.04.1 LTS 本地部署 DeepSeek 私有化知识库
  • QT QLineEdit如何支持文件拖放
  • 项目2 数据可视化--- 第十五章 生成数据
  • 【开源免费】基于SpringBoot+Vue.JS个人博客系统(JAVA毕业设计)
  • 在Nodejs中使用kafka(四)消息批量发送,事务
  • Ollama 部署本地 Deepseek-R1 大模型及可视化聊天工具指南
  • springboot399-中文社区交流平台(源码+数据库+纯前后端分离+部署讲解等)
  • mapbox基础,使用geojson加载circle圆点图层