Java 数组

Posted Naion

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 数组相关的知识,希望对你有一定的参考价值。

一、数组的基本概念

1、什么是数组

    数组是相同类型元素的集合。创建数组的时候,Java就会再内存中分配一段连续的空间来存放数组的内容。每一个数组内容都有自己的编号,这个编号从0开始的,也就是数组的下标从0开始。通过数组的下标来访问数组的内容。

2、一维数组的创建和初始化

创建一个数组:

T[] 数组名 = new T[N];

T:数组中元素的类型。

T[]:表示是数组类型,[]也可以放在数组名的后面。这里的[]不能有任何的数组

N:创建数组要的长度。 

比如:

int[] array1 = new int[10]; // 创建一个可以容纳10个int类型元素的数组
double[] array2 = new double[5]; // 创建一个可以容纳5个double类型元素的数组
String[] array3 = new String[3]; // 创建一个可以容纳3个字符串元素的数组

要对数组进行初始化,有两种方式。

静态初始化:知道数组的内容,就可以静态初始化。

int[] arr =  1,2,3,4 ; //省略情况
int[] arr = new int[]  1,2,3,4 ;//可以省略new int[]

上面两种初始化的方式是没有区别的。

如果不知道数组的内容,那么就可以使用动态初始化。

int[] arr = new int[10]; //定义10个int类型的数组

上面两种创建方式都可以分两步进行创建:

int[] array1;
array1 = new int[10];
int[] array2;
array2 = new int[]10, 20, 30;
// 注意省略格式不可以拆分, 否则编译失败
// int[] array3;
// array3 = 1, 2, 3;

    如果没有对数组进行初始化,数组中的元素有默认值。不同的数据类型有不同的默认值,如果是简单类型,大多是默认值为0。float是0.0f,double是0.0,char是/u0000,boolean是false;引用类型比如字符串类型则是null。

二、一维数组的使用

1、数组元素的访问

数组在内存中是一段连续的空间,下标是从0开始的。比如:

int[]array = new int[]10, 20, 30, 40, 50;
System.out.println(array[0]);
System.out.println(array[1]);
System.out.println(array[2]);
System.out.println(array[3]);
System.out.println(array[4]);

当然,我们可以对数组的内容进行修改。将上面的array[0]改为20:

array[0] = 20;
System.out.println(array[0]);

在Java中,数组[]里面的大小支持常量,变量和表达式。

这在C语言中,C99之前是不行的。 

    数组是一段连续的内存空间,因此支持随机访问,即通过下标访问快速访问数组中任意位置的元素。数组的下标从0开始,介于[0, N)之间不包含N,N为元素个数,不能越界,否则会报出下标越界异常。

int[] array = 1, 2, 3;
System.out.println(array[3]); // 数组中只有3个元素,下标一次为:0 1 2,array[3]下标越界

    上面的结果报出了一个数组越界的异常。当下标是3的时候,说明越界了。这样的错误发生在main函数的第12行。通过这个,可以很快的找到问题的所在。

2、数组的遍历

在Java中,对数组的遍历有两种方式:第一种是for,第二种是增强for(foreach)。

    由于Java是面向对象的语言,在Java中,一切都是对象,比如数组。数组这个对象有它的属性,比如数组的长度等,基于这一点,我们可以不用刻意知道数组的长度,使用.length来获取数组的长度。

//for
int[]array = new int[]10, 20, 30, 40, 50;
for(int i = 0; i < array.length; i++)
    System.out.println(array[i]);
//foreach
int[] array = 1, 2, 3;
for (int x : array) 
System.out.println(x);

//说明:
//int x :array
//数组中的数据类型+变量名,这里array数组里面的类型是int
//array是数组名
//foreach
double[] array = 1.0, 2.0, 3.0;
for (double x : array) 
System.out.println(x);

增强for循环是得不到数组的下标的,所以它一般用于数组的遍历,比如数组累加这样的操作。

三、数组在内存中的分布

1、JVM内存分布简介

    要了解数组在内存里面的情况,就要知道Java内存分布是什么样的,这里做必要的介绍。Java经过编译后产生的.class文件被加载到JVM虚拟机里面的本地方法栈里面运行。为了高效管理内存,JVM对内存进行了划分。JVM是一个软件,由C/C++编写的软件。这是因为系统之类的由C/C++代码编写比较高效。

 说明:

(1)Java虚拟机栈:也是我们在Java中常说栈。一般用来存放局部变量。

(2)本地方法栈:运行由c/c++编写的代码。经过编译产生的.class文件被加载到这里运行。

(3)堆:是Java中最大的一块内存空间。只要是对象,都是在堆上开辟的。在堆里面的引用叫对象。堆上的内存是不需要进行手动释放的,Java有自己的垃圾回收机制。

(4)程序计数器:保存一些指令和信息等。

(5)方法区:存放常量,静态成员变量等。

这里重点关心堆和虚拟机栈。

2、引用类型变量

    引用类型创建的变量,一般称为对象的引用。存储的是对象所在空间的地址。如何理解数组的引用呢?比如写了这么一个代码:

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

在内存中发生了什么呢?

    这里的arr是局部变量,运行代码后,java就会在栈上为arr分配空间。后面new了之后,就会在堆上开辟一块空间来保存这些内容。arr存的是后面对象的地址。这里要强调的是,引用变量存的是对象的地址。

现在我们直接打印arr看看:

    打印出了这么一个地址(可以理解为数组首元素地址)。这里的地址为了安全,经过了特殊的处理,是这个引用对象的哈希地址。@之后的是哈希地址,@前的I表示这是一个int型,[表示是一个数组。arr这个引用,引用(指向)了一个数组对象。在比如以下代码:

int[] arr = new int[]  1,2,3,4 ;
int[] brr = arr;//???
System.out.println(arr);
System.out.println(brr);

这里打印出来的地址是一样的,说明brr也引用了与arr相同的对象。

现在我们打印出这两个数组的内容看看:

在brr里面修改brr[0]的值:

    要注意这里的brr=arr,是把arr的值给了brr。arr引用了这个对象,brr引用了arr引用的对象,而不是brr指向arr(换句话来说,就是引用指向引用)。

那么要注意的几点:

(1)引用不能指向引用,引用指向了对象(引用的对象)。

(2)一个引用,不能同时引用多个对象。

这里的arr引用新的对象的时候,没有同时引用。

(3)引用不一定在栈上。还有可能在堆上,比如成员变量。

(4)引用赋值为null表示不指向任何对象。

3、例题

public static void fun1(int[] array) 
    array = new int[]  5,6,7,8 ;



public static void fun2(int[] array) 
    array[0] = 2;


public static void main(String[] args) 

    int[] arr = new int[]  1,2,3,4 ;
    fun1(arr);
    System.out.println(Arrays.toString(arr));
    int[] brr = new int[]  1,1,1,1 ;
    fun2(arr);
    System.out.println(Arrays.toString(arr));

分别打印出来的结果是?

第一个的图示:

第二个和之前的是相同的。

四、二维数组

1、二维数组定义

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

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

int[][] arr1 =  1,2,3,4,5,6 ;
int[][] arr2 = new int[][]  1,2,3,4,5,6 ;
int[][] arr3 = new int[2][3];
int[][] arr4 = new int[2][];

    在Java中,如果是前两种定义的方式,必须要手动加括号。同时,行是必须要指定的,列可以不用指定。

2、二维数组遍历

和一维数组类似,二维数组有for循环和foreach循环来进行遍历。

int[][] arr1 =  1,2,3,4,5,6 ;
//for
for (int i = 0; i < arr1.length; i++) 
    for (int j = 0; j < arr1[i].length; j++) 

         System.out.print(arr1[i][j] + " ");
     
     System.out.println();

//foreach
for (int[] x : arr1) 
    for (int y : x) 
        System.out.print(y + " ");
    
    System.out.println();

五、数组常用的方法

    Java中的Arrays工具类包括了数组常用的一些方法,比如数组的排序,数组的拷贝等方法,而这些方法,在我们的日常生活中也是经常使用的。在使用之前需要导入:import java.util.Arrays;

    这些方法是重构的,这里拿int类型的数组简单介绍一下,其他的原理是相同的。具体的内容见官方文档。

1、Arrays.toString方法

将一维数组变成字符串。二维数组使用Arrays.deepToString方法。

public static String toString(int[] a)

参数

a - 要返回其字符串表示形式的数组

public static void main(String[] args) 
    int[] array = new int[]  1,2,3,4 ;
    System.out.println(Arrays.toString(array));//[1,2,3,4]

2.1、Arrays.copfOf方法

从0下标来时复制指定长度数组的内容到新的数组中。

public static int[] copyOf(int[] original, int newLength)

参数

original - 要复制的数组

newLength - 要返回的副本的长度

public static void main(String[] args) 
    int[] array = new int[]  1,2,3,4 ;
    int[] ret = Arrays.copyOf(array,2);
    System.out.println(Arrays.toString(ret));//[1,2]

2.2、Arrays.copyOfRange方法

和Arrays.copfOf方法类似,这个是指定范围的拷贝。范围是左闭右开区间。

public static int[] copyOfRange(int[] original, int from, int to)

参数

original - 要从中复制范围的数组

from - 要复制的范围的初始索引(包括)

to - 要复制的范围的最终索引,除了它本身。 (该索引可能位于数组之外)

public static void main(String[] args) 
    int[] array = new int[]  1,2,3,4 ;
    int[] ret = Arrays.copyOfRange(array,2,4);
    System.out.println(Arrays.toString(ret));//[3,4]

3、Arrays.sort方法

对数组进行升序排序。

public static void sort(int[] a)

public static void main(String[] args) 
    int[] array = new int[]  4,3,2,1 ;
    Arrays.sort(array);
    System.out.println(Arrays.toString(array));//[1,2,3,4]

4、Arrays.fill方法

对数组内容进行指定填充。

public static void fill(int[] a, int val)//全部填充

参数

a - 要填充的数组

val - 要存储在数组的所有元素中的值

public static void fill(int[] a, int fromIndex, int toIndex, int val)//指定范围填充

参数

a - 要填充的数组

fromIndex - 要用指定值填充的第一个元素(包括)的索引

toIndex - 要用指定值填充的最后一个元素(排除)的索引

val - 要存储在数组的所有元素中的值

public static void main(String[] args) 
    int[] array = new int[10];
    Arrays.fill(array,10);
    Arrays.fill(array,2,8,20);
    System.out.println(Arrays.toString(array));

 5、Arrays.equal方法

判断两个数组的内容是否相同

public static boolean equals(int[] a, int[] a2)

参数

a - 要测试相等的一个数组

a2 - 要测试的其他数组是否相等

public static void main(String[] args) 
    int[] arr1 = new int[]  4,3,2,1 ;
    int[] arr2 = new int[]  1,2,3,4 ;
    int[] arr3 = new int[]  1,2,3,4 ;
    System.out.println(Arrays.equals(arr1, arr2));//false
    System.out.println(Arrays.equals(arr2, arr3));//true

 6、Arrays.binarySearch方法

二分查找数组内容,使用前先sort排序数组。

public static int binarySearch(int[] a, int fromIndex, int toIndex, int key)

参数

a - 要搜索的数组

fromIndex - 要搜索的第一个元素(包括)的索引

toIndex - 要搜索的最后一个元素(排他)的索引

key - 要搜索的值

public static void main(String[] args) 
    int[] arr1 = new int[]  4,3,2,1 ;
    System.out.println(Arrays.binarySearch(arr1, 3));//下标是1

java 数组操作实例

对于任何编程语言,数组都是必须掌握的知识点,本文章向大家介绍java数组的一些操作实例。感兴趣的朋友可以参考一下。

  1. Java数组排序及元素查找
  2. Java数组添加元素
  3. Java获取数组长度
  4. Java数组反转
  5. Java数组输出
  6. Java数组获取最大和最小值
  7. Java数组合并
  8. Java数组填充
  9. Java数组扩容
  10. Java数组排序及查找
  11. Java删除数组元素
  12. Java数组差集
  13. Java数组交集
  14. Java在数组中查找指定元素
  15. Java判断数组是否相等
  16. Java数组并集

以上是关于Java 数组的主要内容,如果未能解决你的问题,请参考以下文章

java中如何创建动态数组

java中图像与数组转换

java打印数组

java 怎样传递数组对象

java中怎么删除数组中的元素?

java中如何创建字符串数组?