14、数组的定义与使用

1、 本次预计讲解的知识点

1、 数组的基本作用与定义语法;

2、 二维数组的使用;

3、 数组的方法的互相操作;

4、 与数组有关的类库方法使用;

5、 对象数组。

2、 具体内容

在所有的的开发之中,数组是一个非常重要的概念,所有的项目都有数组,但是它使用的数组的本次讲解有出入的,后面更换数组的使用的形式,但是其基本概念不会被改变。

 

 

2.1、数组的基本概念

数组实质一组相关变量的集合,例如:如果说现在要想定义100个整型变量,按照传统的思路,可能这样定义的:

Int i1,i2,…i100一共希望我100个变量。

以上的形式的的确满足技术要求,但是这里有一个问题,这100变量没有任何的逻辑控制关系,完全独立。那么就会出现对象不方便管理的情况。那么在这种情况下就可以利用数组来解决此类问题,而数组本身也属于引用数据类型,所以数组定义语法如下:

声明并开辟数组数据类型 数组名称[]=new数据类型[长度];

分布完成

声明数组数组类型 数组名称[]=null;

开辟数组:数组名称 =new 数据类型[长度]

当数组来开辟空间之后,那么可以采用“数组名称[下标|索引]”的形式进行访问但是所有的下标对后世从

0下开始的。即:如果是3个长度的数组,那么下标的范围:0~2012一共三个内容)如果访问的时候超过了数组允许下标的长度,那么会出现数组越界异常(ArrayIndexOutOfBoundsException)

以上给出的数组定义结构使用的是动态初始化的方式,即:数组会首先开辟内存空间,但数组中的的都是其对应数据类型的默认值。

由于数组是一种顺序的结构,并且数组额长度都是固定的 ,那么可以使用循环的方式输出,很明显需要知道for循环,而在java里面为方便数组的输出提供有一个“数组名称.length,可以取得数组长度

范例:定义数组

public class ArrayDemo {

public static void main(String[] args) {

//声明并开辟了一个3个长度的数组

int data[] = new int[3];

data[0] = 10;

data[1] = 20;

data[2] = 30;

for(int x =0; x< data.length; x++) {

System.out.println(data[x]);

}

}

 

}

虽然数组的操作比较简单,但是麻烦的问题在于,他也属于引用数组类型,所以以上代码依然需要牵制到

内存分配,与对象保存唯一的区别在于:对象中对内存保存的是一组信息。

以上使用的是第一种数组定义的语法,那么下面更换第二种:

public class ArrayDemo {

public static void main(String[] args) {

int data[] = null;//声明数组

data = new int[3];//开辟数组空间

data[0] = 10;

data[1] = 20;

data[2] = 30;

for(int x =0; x< data.length; x++) {

System.out.println(data[x]);

}

}

 

}

既然数组属于引用数据类型,那么数组一定可以发生引用传递。

范例:数组的引用传递

public class ArrayDemo {

public static void main(String[] args) {

//声明并开辟了一个3个长度的数组

int data[] = new int[3];

data[0] = 10;

data[1] = 20;

data[2] = 30;

int temp[] = data;

temp[0] = 99;

for(int x =0; x< data.length; x++) {

System.out.println(data[x]);

}

}

以上数组的定义格式严格来讲属于动态初始化,它的操作特点:先开辟数组空间,而后为数组中的内容进行赋值。那么在数组定义之中提供静态初始化的操作,即:数组定义的同时就设置好了相应的数据内容,格式如下:

格式一简化格式

数据类型 数组名称 [] = {值,值,….}

格式二完整格式

数据类型 数组名称 [] = new 数据类型{值,值,….}

范例:数组的静态初始化

public class ArrayDemo {

public static void main(String[] args) {

int data[] = new int[]{1,2,3,4,5};

for(int x =0; x< data.length; x++) {

System.out.println(data[x]);

}

}

 

}

在实际的工作中,数组得会存在的,但是它的内容大部分情况下都是通过传递的数据而动态生成的,很少出现这种开辟数组后去使用的情况。

虽然数组支持顺序的数据访问操作,但是数组有一个最大的的缺点 —— 长度不能够改变,所以正因为如此,在我们的开发之中,才不会直接应用数组,但是会使用到数组的概念。

2.2、二维数组(了解)

在之前的数组只有一个[]”,所以此类数组就是普通的数组,或者再麻烦一点可以把它称为一维数组,如果现在想描述更多的数据,可以使用二位数组,后有两个“[]

一维数组严格来讲,类似于如下形式:

索引

0

1

2

3

4

5

6

7

8

数据

90

342

423

435

243

532

45

54

23

如果一维数组里面要找到一个数据,只需要确定一个索引就够了。

二维数组就是一张数据表,有行有列,类似于如下形式:

索引

:0

:1

:2

:3

:4

:5

:6

:7

:8

:0

90

342

423

435

243

532

45

54

23

:1

58

78

78

77

85

875

85

76

867

:2

57

578

5

6

857

87

78

86

75

如果现在想在二维数组里面确定一个数据,需要行和列一起定位,例如:数字77的索引位置:行13[1][3]”而对于二维数组的定义有如下的两类:

动态初始化:数据类型 数组名称[][] = new 数据类型[行的个数][列的个数]

静态初始化;数据类型 数组名称[][] = new 数据类型[][]{{,,},{,,}}

通过定义结构可以发现,所谓数组实际就是将多个一维数组变为的大的数组,并为每一个一维数组设置了一个行号而已。

范例:观察二维数组

public class ArrayDemo {

public static void main(String[] args) {

int data[][] = new int[][]{

{1,2,3},

{4,5,6},

{7,8,9}

};

//外层循环是控制数组的数据行内容

for (int x = 0; x < data.length; x++) {

//内层循环是控制数组的数据列内容

for (int y = 0; y < data[x].length; y++) {

System.out.print(data[x][y]+"\t");

}

System.out.println();

}

}

}

随着开发的发展,直接编写的代码里面很少再出现二维数组的概念。

2.3、数组的方法参数的传递(难点)

在之前所有方法发现传递的数据几乎都是用的基本数据类型,那么除了基本数据类型之外,也可以传递数组,但是传递的数组,请千万记住,观察内存分配图。

范例:一个传递的程序

public class ArrayDemo {

public static void main(String[] args) {

int data[] = new int [] {1,2,3};

change(data);//int temp[] = data;

for (int i = 0;i < data.length; i++) {

System.out.println(data[i]);

}

}

//此方法定在主类中,并且有主方法直接调用

public static void change(int temp[]) {

for (int i = 0;i < temp.length; i++) {

temp[i] *= 2; //将数组的内容乘2保存

}

}

}

public class ArrayDemo {

public static void main(String[] args) {

int data[] = new int [] {1,2,3};

int temp[] = data;

for (int i = 0;i < temp.length; i++) {

temp[i] *= 2;

}

for (int i = 0;i < temp.length; i++) {

System.out.println(data[i]);

}

}

}

在进行引用传递的过程之中,如果方法对数组对数组的修改一定会影响到原始数据。

范例:实现一个数组排序

数组排序需操作在笔试中经常被问到,下面给出(升序)排序的基本原理:

原始数据:219053768

第一次排序:120537689

第二次排序:102356789

第三次排序:012356789

以上只是给出了排序的基础原理过程,但是会根据的不同会出现不同的排序次数,但是不管如何排序有多少的数据,总的排序次数不会超过数组的长度。所以只要排序的次数达到了“长度*长度”,那么所以的数据一定可以排序成功。

l 基础排序

public class ArrayDemo {

public static void main(String[] args) {

int data[] = new int [] {2,1,9,0,5,3,7,6,8};

print(data);

//外层控制排序的次数

for (int i=0; i<data.length-1; i++) {

//内层控制每次的排序控制

for(int y = 0; y < data.length-1; y++ ) {

if (data[y] > data[y+1]) {//需要交换

int temp = data[y];

data[y] = data[y+1];

data[y+1] = temp;

}

}

}

print(data);

}

//专门定义一个输出功能的方法

public static void print(int temp[]) {

for (int i=0; i<temp.length; i++) {

System.out.print(temp[i] + "");

}

System.out.println();

}

}

l 改善设计:主方法设计上是作为程序的起点存在,那么所有的程序起点都可以称为客户端既然是客户端,所有的代码编写编写一定要简单,那么可以采用封装方法

public class ArrayDemo {

public static void main(String[] args) {

int data[] = new int [] {2,1,9,0,5,3,7,6,8};

print(data);

sort(data);//实现排序

print(data);

}

//这个方法专门负责排序

public static void sort(int arr[]) {

//外层控制排序的次数

for (int i=0; i<arr.length-1; i++) {

//内层控制每次的排序控制

for(int y = 0; y < arr.length-1; y++ ) {

if (arr[y] > arr[y+1]) {//需要交换

int temp = arr[y];

arr[y] = arr[y+1];

arr[y+1] = temp;

}

}

}

}

//专门定义一个输出功能的方法

public static void print(int temp[]) {

for (int i=0; i<temp.length; i++) {

System.out.print(temp[i] + "");

}

System.out.println();

}

}

 

面试题:请编写一个数组排序操作

答案入上

范例:实现数组的转置

下面首先解释一下转置的概念(一维数组实现):

原始数组: 12345678

转置后的数组: 87654321

如果转置的操作,有两个思路:

l 定义一个新的数组,而后将原始数组按照倒序的方式插入到新的数组之中,随后改变原始数组引用;

public class ArrayDemo {

public static void main(String[] args) {

int data[] = new int [] {1,2,3,4,5,6,7,8};

print(data);

sort(data);//实现排序

print(data);

}

//这个方法专门负责排序

public static void sort(int arr[]) {

//外层控制排序的次数

for (int i=0; i<arr.length-1; i++) {

//内层控制每次的排序控制

for(int y = 0; y < arr.length-1; y++ ) {

if (arr[y] > arr[y+1]) {//需要交换

int temp = arr[y];

arr[y] = arr[y+1];

arr[y+1] = temp;

}

}

}

}

//专门定义一个输出功能的方法

public static void print(int temp[]) {

for (int i=0; i<temp.length; i++) {

System.out.print(temp[i] + "");

}

System.out.println();

}

}

 

虽然以上的代码实现了转置的操作的,但是遗憾的是,代码会产生垃圾

l 利用算法在一个数组上完成转置操作:

n 原始数组: 12345678;转置次数:数组长度/ 2

n 第一次转置 82345671

n 第二次转置 87345621

n 第三次转置 87645321

n 第四次转置 87654321

但是以上给出的数组长度是一个偶数,如果是一个奇数呢?

n 原始数组: 1234567;转置次数:数组长度/ 2

n 第一次转置 7234561

n 第二次转置 7634521

n 第三次转置 7654321

 

也就是说不管是奇数的个数还是偶数的个数,转置的次数计算的方式是完全一样的。

public class ArrayDemo {

public static void main(String[] args) {

int data[] = new int [] {1,2,3,4,5,6,7,8};

reverse(data);

print(data);

}

//此方法专门实现数组的转置操作

public static void reverse(int arr[]) {

int len = arr.length / 2;//转置次数

int head = 0;//头部索引

int tail = arr.length - 1;//尾部索引

for (int x = 0; x<len; x++) {

int temp = arr[head];

arr[head] = arr[tail];

arr[tail] = temp;

head++;

tail--;

}

}

//专门定义一个输出功能的方法

public static void print(int temp[]) {

for (int i=0; i<temp.length; i++) {

System.out.print(temp[i] + "");

}

System.out.println();

}

}

以上实现的是一维数组的转置,那么如果是二维数组呢?

前提:是行与列完全相同的数组;

1 2 3

4 5 6

7 8 9

第一次转置:4的索引[0][1]2的索引[1][0],行数和列数相同

1 4 3

2 5 6

7 8 9

第二次转置:

1 4 7

2 5 6

3 8 9

第三次转置:

1 4 7

2 5 8

3 6 9

只有行和列相同的时候才会发生交换的操作。

1[x=0][y=0] 2[x=0][y=1] 3[x=0][y=2]

4[x=1][y=0] 5[x=1][y=1] 6[x=1][y=2]

7[x=2][y=0] 8[x=2][y=1] 9[x=2][y=2]

 

第一次转换(x = 0,y = x = 0; 循环3次)

 

第二次转换(x = 1,y = x = 1; 循环2次)

 

第三次转换(x = 2,y = x =2; 循环1次)

 

以上给出的是一个等行列的数组,但是如果不一样呢?

1 2 3

4 5 6

 

开辟一个新的数组,数组的行数是原始数组的列数,数组的列数是原始数组的行数

需要改变原始数组的引用,会产生垃圾。

 

 

以上实现了方法接受数组的操作情况,同样方法也可以返回数组。

范例:方法返回数组

public class ArrayDemo {

public static void main(String[] args) {

int[] data = init();//接受数组

print(data);

//init()方法返回的是一个数组

//数组可以直接使用length取得长度

System.out.println(init().length);

}

public static int[] init() { //方法返回数组

return new int[] {1,2,3,4,5,6,7,8,9};

}

public static void print(int temp[]) {

for (int i=0; i<temp.length; i++) {

System.out.print(temp[i] + "");

}

System.out.println();

}

}

重点关注方法的返回值即可。

2.4数组操作方法

Java本身对于数组是有提供类库的支持的,下面来说两个数组有关的操作。

1、数组的拷贝:可以将一个数组的内容拷贝到另外一个数组之中;

语法:System.arraycopy(源数组名称,源数组拷贝开始索引,目标数组名称,目标数组拷贝开始索引,长度)

范例:实现数组拷贝

数组A12345678

数组B1122334455667788

要求拷贝后的数组B1122567667788

public class ArrayDemo {

public static void main(String[] args) {

int[] dataA = new int[]{1,2,3,4,5,6,7,8,9};

int[] dataB = new int[]{11,22,33,44,55,66,77,88,99};

System.arraycopy(dataA,4,dataB,2,3);

print(dataB);

 

}

 

public static void print(int temp[]) {

for (int i=0; i<temp.length; i++) {

System.out.print(temp[i] + "");

}

System.out.println();

}

}

2、数组排序:之前排序的基本操作,但是在开发中如果进行排序只需要使用如下代码即可

语法:Arrays.sort(数组名称)

范例:实现排序

import java.util.Arrays;

 

public class ArrayDemo {

public static void main(String[] args) {

int[] data = new int[]{3,6,2,4,5,1,8,7,9};

Arrays.sort(data);//排序

print(data);

 

}

 

public static void print(int temp[]) {

for (int i=0; i<temp.length; i++) {

System.out.print(temp[i] + "");

}

System.out.println();

}

}

2.5对象数组

数组是引用类型,而类也是同样是引用类型,所以如果是对象数组的话表示引用类型里面嵌套其他的引用类型。

在之前使用的数组都属于基本数据类型的数组,但是所有引用数据类型也同样可以定义数组,这样的数组称为对象数组。如果想定义对象数组(以类为例),可以采如下形式完成:

动态初始化:开辟之后对象数组的内容都是null值。

声明并初始化对象数组:类名称 对象数组名称 [] = new 类名称[长度]

n 分布完成:

声明对象数组:类名称 对象数组名称 [] = null

开辟对象数组:对象数组名称 = new 类名称[长度]

静态初始化:类名称 对象数组名称[] = new类名称[] {实例化对象,实例化对象,...}

范例:对象数组动态初始化

class Book{

private String title;

private double price;

public Book(String t,double p){

title = t;

price = p;

}

public String getInfo(){

return "书名:" + title + "价格:" + price;

}

}

public class ArrayDemo {

public static void main(String[] args) {

//开辟了一个三个长度的对象数组

Book  books [] = new Book[3];

//对象数组中的每一个数据都需要分别实例化

books[0] = new Book("Java",78.8);

books[1] = new Book("jsp",68.8);

books[2] = new Book("abdroid",88.8);

 

for (int x=0;x<books.length; x++) {

System.out.println(books[x].getInfo());

}

}

 

 

}

对象数组实际就是将多个对象数组同意管理

范例:静态初始化

class Book{

private String title;

private double price;

public Book(String t,double p){

title = t;

price = p;

}

public String getInfo(){

return "书名:" + title + "价格:" + price;

}

}

public class ArrayDemo {

public static void main(String[] args) {

//开辟了一个三个长度的对象数组

Book  books [] = new Book[]{

new Book("Java",78.8),

new Book("jsp",68.8),

new Book("abdroid",88.8)

};

for (int x=0;x<books.length; x++) {

System.out.println(books[x].getInfo());

}

}

}

一般而言,使用对象数组的时候只会定义成一维。

3、总结

1、数组用很少,但是一定会用,而且数组的相关的逻辑关系比较麻烦;

l 数组的排序与转置要明白;

2、一切以一维数组为主要明白数组的定义语法与内存关系(对象一致);

3、对象数组的定义语法,对象数组=多个对象;

4、数组有一个最大的天生短板:长度胡定,所以这就限制了数组在开发中出现

5、数组的排序:Arrays.sort(数组名称)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值