解析java中的数组

简介: 解析java中的数组

数组的定义

数组:本质上就是一组相同类型的变量。

二 数组的基本语法

1) 数据类型[] 数组名称 = new 数据类型 [] { 初始化数据 };
例:int[] arr = new int[]{1, 2, 3};
2) 数据类型[] 数组名称 = { 初始化数据 };
例: int[] arr = {1, 2, 3};
3) 数据类型[] 数组名称 = new int[定义数组长度];//这种定义数组里面全部初始化为零
例:int[] arr = new int[10];

三 数组的使用

1 数组获取长度与访问元素

int[] arr = {1, 2, 3};
// 获取数组长度
System.out.println("length: " + arr.length); // 执行结果: 3
// 访问数组中的元素
System.out.println(arr[1]); // 执行结果: 2

注意事项:

(1): 访问数组元素的下标是从0开始的

(2):下表访问的数不能超过【0,length-1】,否则会出现数组越界,这样程序会报错。

(3):利用[]可以对数组的内容进行更改与读取操作

2 数组的遍历

(1)for循环遍历

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

(2)for-each遍历数组

int[] arr = {1, 2, 3};
for (int x : arr) {
System.out.println(x);
}

四 数组作为方法的参数

(1)基本用法

public static void main(String[] args) {
  int[] arr = {1, 2, 3};
  printArray(arr);
}
public static void printArray(int[] a) {
  for (int x : a) {
  System.out.println(x);
  }
}
// 执行结果
1
2
3

在以上的这个数组中,int[] a 是函数的形参, int[] arr 是函数实参.

(2)理解引用类型

参数传数组类型就是属于引用类型

public static void main(String[] args) {
   int[] arr = {1, 2, 3};
   func(arr);
    System.out.println("arr[0] = " + arr[0]);
}
public static void func(int[] a) {
        a[0] = 10;
       System.out.println("a[0] = " + a[0]);
}
// 执行结果
a[0] = 10
arr[0] = 10

我们发现, 在方法内部修改数组内容, 主函数数组内容也发生改变.

此时数组名 arr 是一个 “引用” . 当传参的时候, 是按照引用传参.

这个就需要我们从内存这个知识去解释了,在内存中,局部变量创建是放在JVM的栈上

,对象是在堆上。在上面这个代码中,首先进入main函数,为arr开辟一个内存空间,放到栈上,里面存放的是对象的地址(0x789),而这里的对象就是对数组的内容(1,2,3)会被放到堆上地址为(0x789),通过地址,arr就能够访问到对象,而之后用到方法,arr会把它的地址传给a,此时JVM的栈上有开辟了一个空间(0x789),通过a,也可以访问到arr的对象,可以进行改写与读操作。

图例:

总结:

所谓的 “引用” 本质上只是存了一个地址. Java 将数组设定成引用类型

五 认识null

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

例题

int[] arr = null;
System.out.println(arr[0]);
// 执行结果
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:6)

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

注意:

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

六. 数组作为方法的返回值

// 返回一个新的数组
class Test {
public static void main(String[] args) {
  int[] arr = {1, 2, 3};
  int[] output = transform(arr);
  printArray(output);
}
public static void printArray(int[] arr) {
  for (int i = 0; i < arr.length; i++) {
 System.out.println(arr[i]);
 }
}
public static int[] transform(int[] arr) {
      int[] ret = new int[arr.length];
      for (int i = 0; i < arr.length; i++) {
      ret[i] = arr[i] * 2;
      }
   return ret;
  }
}

从以上代码分析可以得出,数组可以作为返回值类型,从而返回一个数组,特别注意一下这个ret数组,这个ret数组里面存放的地址不在是arr内存中的地址,此时的ret数组里面的内容会与arr的内容一致。

七 数组的拷贝

1 copyof

import java.util.Arrays;//这个是导入的包,在下面使用Arrays后自动导入

public class java1027 {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        int[] ret = Arrays.copyOf(arr,arr.length);//arr表示要进行拷贝的数组,arr.length表示拷贝的长度
    }

注意这里拷贝的长度可以是乘以一个实数,比如乘以2,那么拷贝后ret数组就变成{1,2,3,4,5,0,0,0,0,0}这个就是扩容处理

2 copyRange

import java.util.Arrays;

public class java1027 {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        int[] ret = Arrays.copyOfRange(arr,2,4);//arr表示原数组,2表示的是拷贝的起始位置,4表示拷贝结束的位置
    }

3 clone()

public class java1027 {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        int[] ret = arr.clone();
    }

4 System.arraycopy

import java.util.Arrays;

public class java1027 {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        int[] ret = new int[arr.length];
        System.arraycopy(arr,0,ret,0,arr.length);
        System.out.println(Arrays.toString(ret));//数组以字符串的形式输出
    }//arr表示的是原数组,0表示从原数组0下标开始拷贝,ret表示目的数组,0表示从下标0开始,arr.length表示结束下标

以上四种拷贝方式都是属于浅拷贝,至于深拷贝,后续的内容我们会详解

八. 二维数组

1 基本语法

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

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


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

运行结果

2

3

二维数组arr从这张图就可以看出二维数组是一个特殊的一维数组,结合上诉代码就可以看出arr.length代表的是整个行的长度,arr[0].length(或者arr[1].length)代表的是列的长度。知道这个之后就可以遍历二维数组的内容了,

2 二维数组的遍历

(1)for循环进行遍历


public class java1027 {
    public static void main(String[] args) {
    int[][] arr = {{1,2,4},{1,2,3}};
        for (int i = 0; i < arr.length; i++) {//访问行
            for (int j = 0; j < arr[i].length; j++) {//访问列
                System.out.print(arr[i][j]+" ");

            }
            System.out.println();
        }
    }

运行结果

1 2 4

1 2 3

(2)for-each循环遍历

public class java1027 {
    public static void main(String[] args) {
    int[][] arr = {{1,2,4},{1,2,3}};
        for (int[] ret:arr) {
            for (int x:ret) {
                System.out.print(x+" ");
            }
            System.out.println();
        }
    }

(3)调用Arrays

import java.util.Arrays;

public class java1027 {
    public static void main(String[] args) {
    int[][] arr = {{1,2,4},{1,2,3}};
   System.out.println(Arrays.deepToString(arr));
    }

运行结果

[[1, 2, 4], [1, 2, 3]]

3 不规则的二维数组

public class java1027 {
    public static void main(String[] args) {
    int[][] arr = new int[2][];
    arr[0]=new int[3];
    arr[1]=new int[2];
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j]+" ");
            }
            System.out.println();
        }

    }

运行结果

0 0 0

0 0

目录
相关文章
|
1月前
|
缓存 安全 Java
Java并发性能优化|读写锁与互斥锁解析
本文深入解析Java中两种核心锁机制——互斥锁与读写锁,通过概念对比、代码示例及性能测试,揭示其适用场景。互斥锁适用于写多或强一致性场景,读写锁则在读多写少时显著提升并发性能。结合锁降级、公平模式等高级特性,助你编写高效稳定的并发程序。
73 0
|
1月前
|
安全 Oracle Java
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
118 0
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
|
15天前
|
算法 Java 测试技术
零基础学 Java: 从语法入门到企业级项目实战的详细学习路线解析
本文为零基础学习者提供完整的Java学习路线,涵盖语法基础、面向对象编程、数据结构与算法、多线程、JVM原理、Spring框架、Spring Boot及项目实战,助你从入门到进阶,系统掌握Java编程技能,提升实战开发能力。
58 0
|
2月前
|
存储 Java Linux
操作系统层面视角下 Java IO 的演进路径及核心技术变革解析
本文从操作系统层面深入解析Java IO的演进历程,涵盖BIO、NIO、多路复用器及Netty等核心技术。分析各阶段IO模型的原理、优缺点及系统调用机制,探讨Java如何通过底层优化提升并发性能与数据处理效率,全面呈现IO技术的变革路径与发展趋势。
44 1
|
2月前
|
并行计算 Java API
Java List 集合结合 Java 17 新特性与现代开发实践的深度解析及实战指南 Java List 集合
本文深入解析Java 17中List集合的现代用法,结合函数式编程、Stream API、密封类、模式匹配等新特性,通过实操案例讲解数据处理、并行计算、响应式编程等场景下的高级应用,帮助开发者提升集合操作效率与代码质量。
116 1
|
2月前
|
安全 Java API
Java 集合高级应用与实战技巧之高效运用方法及实战案例解析
本课程深入讲解Java集合的高级应用与实战技巧,涵盖Stream API、并行处理、Optional类、现代化Map操作、不可变集合、异步处理及高级排序等核心内容,结合丰富示例,助你掌握Java集合的高效运用,提升代码质量与开发效率。
175 0
|
2月前
|
安全 JavaScript Java
java Web 项目完整案例实操指南包含从搭建到部署的详细步骤及热门长尾关键词解析的实操指南
本项目为一个完整的JavaWeb应用案例,采用Spring Boot 3、Vue 3、MySQL、Redis等最新技术栈,涵盖前后端分离架构设计、RESTful API开发、JWT安全认证、Docker容器化部署等内容,适合掌握企业级Web项目全流程开发与部署。
113 0
|
2月前
|
安全 Java
Java编程探究:深入解析final关键字
1. **使用限制**: 对于 `final` 方法和类,可以限制其他开发人员对代码的使用,确保其按设计的方式工作而不会被子类意外改变。
77 0
|
2月前
|
存储 安全 算法
Java 核心知识与技术全景解析
本文涵盖 Java 多方面核心知识,包括基础语法中重载与重写、== 与 equals 的区别,String 等类的特性及异常体系;集合类中常见数据结构、各集合实现类的特点,以及 HashMap 的底层结构和扩容机制;网络编程中 BIO、NIO、AIO 的差异;IO 流的分类及用途。 线程与并发部分详解了 ThreadLocal、悲观锁与乐观锁、synchronized 的原理及锁升级、线程池核心参数;JVM 部分涉及堆内存结构、垃圾回收算法及伊甸园等区域的细节;还包括 Lambda 表达式、反射与泛型的概念,以及 Tomcat 的优化配置。内容全面覆盖 Java 开发中的关键技术点,适用于深
|
2月前
|
缓存 安全 前端开发
Java 核心知识点与实战应用解析
我梳理的这些内容涵盖了 Java 众多核心知识点。包括 final 关键字的作用(修饰类、方法、变量的特性);重载与重写的区别;反射机制的定义、优缺点及项目中的应用(如结合自定义注解处理数据、框架底层实现)。 还涉及 String、StringBuffer、StringBuilder 的差异;常见集合类及线程安全类,ArrayList 与 LinkedList 的区别;HashMap 的实现原理、put 流程、扩容机制,以及 ConcurrentHashMap 的底层实现。 线程相关知识中,创建线程的四种方式,Runnable 与 Callable 的区别,加锁方式(synchronize

热门文章

最新文章

推荐镜像

更多
  • DNS