数组的作用

在执行程序的过程中,通常会需要存储大量数据。如果只有少量数据,那么通过声明变量,存储到变量中即可。但当我们的数据是20个、40个甚至是100以上时,就意味着需要声明很多变量,这是不现实的,不仅影响程序阅读,而且效率低下,不符合程序优化。这时就需要采用一个有条理并且高效的方法来存储大量数据。

数组是一种数据结构,可以用它来存储元素数量固定且元素类型相同的有序集。 若要存储100个int型的数据,可将它们存储到到一维数组中。 例如:int[] values = new int[100]; 一维数组和二维数组及多维数组的区别后续说明。

数组一旦创建,大小就固定,所以要注意元素数量是否大于数组长度。访问数组元素时,通过下标进行访问,数组第一位下标从0开始,所以数组最后一位下标,为数组长度-1。访问数组的第一位元素: values[0], 第二位元素:values[1] , 以此类推。

简单理解:数组是用于存储同类型数据的集合,而变量是存储单个数据。所以可以将数组看作一个存储相同类型的变量集合,将数组理解为一次性声明多个同类型的变量,并 统一管理。

定义一维数组

声明一维数组  elementType[] name; //元素类型[] 数组名

创建一维数组  new elementType[size]; //通过new操作符,创建指定类型和指定大小的数组。

注意:声明一个数组变量并不会在内存中开辟空间,它只是创建一个对数组引用的存储位置,用于指向数组的内存地址。如果数组变量未指向一个数组引用,则默认值为null,表示引用为空。 这里可以间接表明数组是一种对象类型(引用类型)。

通常情况下,声明数组和创建数组是一次完成,例如:String[] str = new String[10];  创建一个大小为10,String类型的数组,并将其数组引用赋给数组变量str。通常来讲,将str变量称为数组即可,它们的区别可以忽略。

此时str数组是没有元素的,给数组元素赋值:

1         String[] str = new String[10];
2 str[0] = "Java"; //第一位元素赋值
3 str[1] = "C++"; //第二位元素赋值
4 str[2] = "Python"; //第三位元素赋值
5 //.........依次类推,直到str[str.length-1]

如果已经知道数据,并且不多的情况,可以使用数组的初始化语法简化操作,两种方式都一样,推荐第一种。

        String[] str = {"Java","C++","Python"};
String[] str = new String[]{"Java","C++","Python"};

注意:如果定义了数组,但未对数组元素进行初始化,那么数组元素会自动赋予默认值。 基本类型按照默认值规则,引用类型的默认值全部是null。

处理数组

当对数组元素进行操作,例如对数组某个下标的元素进行修改,或者遍历数组所有元素。通常都会使用for循环。
获取数组的几种遍历方式,for循环更加简洁。

//while遍历方式
int i = 0;
while(i<str.length){
System.out.print(str[i] + " ");
i++;
}
//for遍历方式
for(int i=0; i<str.length; i++){
System.out.print(str[i] + " ");
}

除了通过下标遍历数组之外,java还有一个foreach循环,可以不通过下标来顺序地遍历数组。

for(String s : str){
System.out.print(s + " ")
}

注意:foreach循环中对遍历的数组元素操作不会影响原来的数组元素,因为这里的s相当于形参。但如果我们想从指定位置遍历或修改某个数组元素时,则必须采用下标。

复制数组的操作和传递数组参数给方法

要复制数组元素可以使用三种方式:

  1. for循环或foreach遍历取值,赋值给另一个同类型长度相同的数组。
  2. 采用System.arraycopy() 方法。
  3. 使用clone()方法。
        //1.将数组元素复制给另一个数组
for(int i = 0; i < arr.length; i++ ) {
destArr[i] = arr[i];
} //2.使用System.arraycopy()
int[] copyArr = new int[arr.length * 2]; //建议目标数组长度增加2倍,可以容纳更多元素
//参数说明: 源数组 要复制的元素起始位置 目标数组 复制的开始位置 复制的元素长度
System.arraycopy(arr, 0, copyArr, 0, arr.length);
int[] arr = {12,15,30,35};
//注意:数组变量是引用类型,这里是将arr指向的数组引用赋给assignArr,两者本质上是同一个数组
int[] assignArr = arr;
assignArr[0] = 55;
System.out.println(arr[0]); // 55 //3.采用clone(),相当于开辟一个新的内存空间
int[] cloneArr = arr.clone();
cloneArr[0] = 60;
System.out.println(cloneArr[0]); //60
System.out.println(arr[0]); //50

将数组作为参数传递给方法

数组传递给方法和将参数值传递给方法是有很大不同的。Java是按值传递,所以传递基本类型数据时,传的是变量的值,所以对形参操作对实参不会产生影响。但传递数组则是传递该数组的引用地址,对该形参操作时,会影响实参。

    public static void main(String[] args) {
int[] arr = {1,2,3};
testArray(arr);
System.out.println(Arrays.toString(arr)); //[2, 1, 3]
testArray(arr[0], arr[1]);
System.out.println(Arrays.toString(arr)); //[2, 1, 3]
}
//传递数组
public static void testArray(int[] arr) {
int temp = arr[0];
arr[0] = arr[1];
arr[1] = temp;
} //传递数组元素
public static void testArray(int a, int b) {
int temp = a;
a = b;
b = temp;
}

所以使用时,要注意区分传递的参数是基本数据类型还是引用类型。

二维数组

一维数组存储线性的元素集合,而二维数组可以存储矩阵和表格这种形式的数据。一维数组存储值,而二维存储的是一维数组的引用。三维数组中则存储的是二维数组,所以可以将多维看作“数组的数组”。二维数组中的元素通过两个下标来访问,这两个下标代表行和列。

定义一个二维数组,例如: int[][] test= new int[3][4]; //定义一个3行4列,int类型的二维数组。

二维第一个下标表示行,第二个下标表示列。行和列的下标都是从0开始,如图所示 :

        //二维数组元素初始化
int[][] test = new int[3][4];
test[0][0] = 1; //第一行第一列
test[0][3] = 4; //第一行最后一列
test[1][0] = 5; //第二行第一列
test[1][3] = 8; //第二行最后一列
//......
//已知数据情况下,简便二维元素初始化操作
int[][] test = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,13}};

可以很清楚地看到,每一行的数据都用一维数组来存储。二维访问元素时的[i][j],  [i]负责查找行(二维中的一维数组),[j]负责查找列(一维数组中的j下标元素)。

        test[0]; //指向二维中第一位一维数组元素
test[1]; //指向二维中第二位一维数组元素
test[2]; //指向二维中第三位一维数组元素

二维数组的长度就是其中存储的一维数组的数量。

如果只定义二维数组的长度,但没有定义一维的长度,赋值方式如下:

         //定义了二维长度,未定义其中的一维长度
int[][] arr = new int[5][];
System.out.println(arr[0]); //这时的二维数组元素相当于指向null arr[0] = new int[5];//为二维数组元素赋值
arr[1] = new int[3];//为二维数组元素赋值
arr[2] = new int[2];//为二维数组元素赋值
//....

处理二维数组

关于处理数组的几种方式前面已经介绍了,这次采用for循环来遍历二维数组。

        //遍历二维数组
for(int i = 0; i < arr.length; i++) {
//这里是关键,访问arr[i],对arr[i]进行遍历,就是在遍历一维数组
for(int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
}

二维数组测试题

1.求某个二维数组中所有元素的和

2.对某个二维数组按列求和(矩阵形式,不然会导致索引越界)

3.求哪一列的和最大(能解决这个,就能解决哪一行的和最大问题)

若要练习更多二维数组的题目,可自行上网查阅。

三维数组

二维数组中存储一维数组,而一个三维数组则存储是二维数组。 三维数组的定义方式:

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

arr三维数组表示:能存放3个二维,二维中能存放3个一维,一维中能存放2个元素。

三维数组不常用, 这里只简单了解一下。例如存放30天中,每天的每个小时的湿度和温度。

可以用double[][][] weather = [30][24][2]; //建模思路: 湿度和温度可以用一维存放, 二维开辟24空间,一个一维表示当前小时的温度和湿度。三维开辟30空间,用于存放30天的天气。

[0][0][0] //获取第一天,1小时时候的湿度

[0][0][0] //获取第一天,1小时时候的温度

//....

[29][23][0] //获取第30天,24小时时候的湿度

[29][23][1] //获取第30天,24小时时候的温度

另外关于数组的排序,有多种排序方式,即可以自己实现,也可以调用Arrays工具类来进行排序。

除了常规方式创建数组,简单了解通过反射来创建数组。
使用Array类的方法
static Object newInstance(Class<?> cla , int...dimension) 
根据传入的Class实例来声明类型,根据可变参数dimension来决定创建一维还是多维
static get(Object obj,int index)  : 获取指定对象数组中index值
static getXxx(Object obj,int index) : Xxx代表值类型,如果存储的是值类型,就使用该方式
static set(Object obj,int index)  : 设置指定对象数组中index值
static setXxx(Object obj,int index) : Xxx代表值类型,如果该对象数组是存储值类型,就使用该方式

//创建一个字符串类型的三维数组
Object arr = Array.newInstance(String.class,2,3,3); //2层3行3列
//获取该三维数组中的元素,得到二维数组
Object arr2 = Array.get(arr,0); //arr2数组是一个二维数组
System.out.println(arr2); //输出arr,得到二维数组地址

如果要遍历该三维数组arr,必须强制转换成常规数组类型。

String[][][] strArr = (String[][][])arr;

需要注意点就是对象数组中储存的类型是值类型还是引用类型,然后根据不同类型去调用setXxx()或set()方法;

数组的定义和使用,理解多维数组和Array类的更多相关文章

  1. [Swift]多维数组的表示和存储:N维数组映射到一维数组(一一对应)!

    数组:有序的元素序列. 若将有限个类型相同的变量的集合命名,那么这个名称为数组名.组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量.用于区分数组的各个元素的数字编号称为下标.数组 ...

  2. 数组的三种方式总结 多维数组的遍历 Arrays类的常用方法总结

    一.数组的三种声明方式总结 public class WhatEver { public static void main(String[] args) { //第一种 例: String[] tes ...

  3. 首先定义一个5X8的二维数组,然后使用随机数填充满。借助Arrays的方法对二维数组进行排序。

    package day02; import java.util.Arrays; import java.util.Random; public class Test01 { public static ...

  4. Java数组声明创建和使用以及多维数组、Arrays类、稀疏数组

    目录 数组概述 数组声明创建 内存分析 java内存分析 堆 栈 方法区 三种初始化 静态初始化 动态初始化 数组的默认初始化 数组的四个基本特点 数组边界 小结: 数组使用 数组基础使用 For E ...

  5. jQuery写省级联动列表,创造二维数组,以及如何存/调用二维数组中的数据

    jQuery写省级联动列表,创造二维数组来存放数据,然后通过each来遍历调用,通过creatTxtNode创建文本节点,通过createElement创建标签option,在通过append将文本写 ...

  6. php 把一个一维数组的值依次赋值到二维数组中的每一项

    Array( [0] => 1 [1] => 4 [2] => 2 [3] => 6 ) Array( [0] => Array ( [field_name] => ...

  7. js循环一维数组按指定长度截取为二维数组

    //随便创建一个数组 let data = "abcdefghijklmnopkrstuvw12322999".split(""); //总数组 let pro ...

  8. 在C中定义一个动态的二维数组

    一般来讲两种办法: 第一种:连续内存分配 #include "stdio.h" #include "stdlib.h" int main() { int x,y ...

  9. C二维字符数组的使用及如何获取二维数组的总行数和总列数!

    #include <stdio.h> #include <stdlib.h> int main(){ char str[][30] = {"zhangsan" ...

随机推荐

  1. Web开发须知的浏览器内幕 缓存与存储篇(1)

    本文禁止转载,由UC浏览器内部出品. 0.前言 大纲 浏览器缓存和存储相关的功能分为四类: 加载流程 Memory Cache Application Cache(简称AppCache) HTTP C ...

  2. C#代码处理网页关于登录的code

    作者:血饮狂龙链接:https://www.zhihu.com/question/49452639/answer/117294801来源:知乎著作权归作者所有,转载请联系作者获得授权. private ...

  3. CSS技巧教程:margin在IE中的表现

    margin的位移方向是指margin数值为正值时候的情形,如果是负值则位移方向相反. 如上图所示:黄色子元素盒的margin-top,margin-left为负值时,如-10px,则黄色子元素盒向上 ...

  4. Springmvc和Mybatis中常用的注解

    使用注解来构造IoC容器 用注解来向Spring容器注册Bean.需要在applicationContext.xml中注册<context:component-scan base-package ...

  5. CSS盒子模型中()是透明的,这部分可以显示背景()

    CSS盒子模型中()是透明的,这部分可以显示背景() border margin padding content 我的理解: ·       Margin(外边距) - 清除边框外的区域,外边距是透明 ...

  6. Mybatis源码解析优秀博文

    最近阅读了许久的mybatis源码,小有所悟.同时也发现网上有许多优秀的mybatis源码讲解博文.本人打算把自己阅读过的.觉得不错的一些博文列出来.以此进一步加深对mybatis框架的理解.其实还有 ...

  7. C# 按位或,按位与, 按位异或

    a != b  ----->  a = a | b  , a 或者 b 只要有一个为 1, 那么,a 的最终结果就为 1 a &= b  ----->  a = a & b ...

  8. [tools]notepad++当前文件路径不是工作路径

    Time:2015/04/09 描述: 在notepad++中运行lua,工作路径不是当前文件的路径,而是notepad++的安装目录 修改: 把差将中的NppExec --> Follow $ ...

  9. Python 执行命令行操作。

    os.system os.popen() commands.getstatusoutput(cmd) (status, output) = commands.getstatusoutput('cat ...

  10. [T-ARA][20090729]

    歌词来源:http://music.163.com/#/song?id=484058959 在基本发音规则之上,考虑到了音变的某些情况,最后结合听力搞定的一版歌词发音(只要学完养乐多老师的教程应该读起 ...