数组
一、概述
1. 数组的概念:相同数据类型元素的集合
2. 数组的作用:用来存储基本数据类型和引用数据类型的数据
3. 数组可以看成是多个相同类型数据组合,对这些数据的统一管理。
4. 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。
5. 数组的元素可以是任何数据类型,包括基本类型和引用类型。
6. C和C++中的数组都可以分配在栈上面,而JAVA中的数组是只能分配在堆上面的,因为JAVA中的数组是引用类型。
二、常用操作
查看代码
1 public class TestArray {
2 public static void main(String[] args) {
3 /**
4 * 1. 数组的初始化
5 */
6 // 1.1 数组的静态初始化
7 int[] array1 = { 1, 3, 5, 6, 7, 2, 4, 10 };
8
9 // 1.2 数组的动态初始化
10 int[] array2 = new int[5];
11 array2[0] = 1;
12 array2[1] = 2;
13 array2[2] = 7;
14 array2[3] = 3;
15 array2[4] = 4;
16
17 /**
18 * 2. 数组的遍历
19 */
20 // 2.1 for循环打印数组
21 for (int i = 0; i < array2.length; i++) {
22 System.out.print(array2[i]);
23 }
24
25 // 2.2 foreach打印数组
26 for (int i : array2) {
27 System.out.print(i);
28 }
29
30 /**
31 * 3. 数组排序
32 */
33
34 // 3.1 冒泡排序
35 for (int i = 0; i < array2.length; i++) {
36 for (int j = i + 1; j < array2.length; j++) {
37 // 1. 比较相邻元素,将较大的数冒泡
38 if (array2[i] > array2[j]) {
39 // 2. 交换
40 int temp = array2[i];
41 array2[i] = array2[j];
42 array2[j] = temp;
43 }
44 }
45 }
46 for (int i : array2) {
47 System.out.println(i);
48 }
49
50 // 3.2 选择排序
51 for (int i = 0; i < array2.length; i++) {
52 int min = i;
53 for (int j = i; j < array2.length; j++) {
54 // 1. 找到最小的数
55 if (array2[j] < array2[min]) {
56 // 2. 将最小的数赋值给min
57 min = j;
58 }
59 }
60 // 3. 交换两个数的位置
61 int temp = array2[i];
62 array2[i] = array2[min];
63 array2[min] = temp;
64 }
65 for (int i : array2) {
66 System.out.println(i);
67 }
68
69 // 3.3 反转排序
70 for (int i = 0; i < array2.length / 2; i++) {
71 // 将第i位元素与array2.length-1-i位元素交换
72 int temp = array2[i];
73 array2[i] = array2[array2.length - 1 - i];
74 array2[array2.length - 1 - i] = temp;
75 }
76 for (int i : array2) {
77 System.out.println(i);
78 }
79
80 // 3.4 插入排序
81 for (int i = 0; i < array2.length; i++) {
82 int j = i;
83 int tmp = array2[i];
84 for (; j > 0 && tmp < array2[j - 1]; j--) {
85 // 1. 将大于待排序的数向后移
86 array2[j] = array2[j - 1];
87 }
88 // 2. 交换
89 array2[j] = tmp;
90 }
91 for (int i : array2) {
92 System.out.println(i);
93 }
94 }
95 }
三、Arrays工具类
查看代码
1 package pers.mj;
2
3 import static org.hamcrest.CoreMatchers.instanceOf;
4
5 import java.util.Arrays;
6 import java.util.List;
7
8 import org.junit.Test;
9
10 public class Demo {
11 @Test
12 public void test() {
13
14 int[] array1 = { 1, 3, 5, 2, 4 };
15 int[] array2 = { 3, 2 };
16
17 // 1. 排序
18 Arrays.sort(array2);
19 for (int i : array2) {
20 System.out.print(i);
21 }
22
23 // 2. 二分法查找
24 System.out.print(Arrays.binarySearch(array2, 3));
25
26 // 3. 数组元素比较
27 System.out.println(Arrays.equals(array1, array2));
28
29 // 4. 数组元素填充
30 Arrays.fill(array2, 1);
31 for (int j : array2) {
32 System.out.println(j);
33 }
34
35 /**
36 * aslist详解
37 * 1. 该方法适用于对象型数据的数组(String、Integer...)
38 * 2. 该方法不建议使用于基本数据类型的数组(byte,short,int,long,float,double,boolean)
39 * 3. 该方法将数组与List列表链接起来:当更新其一个时,另一个自动更新
40 * 4. 不支持add()、remove()、clear()等方法
41 */
42
43 // 1、对象类型(String型)的数组数组使用asList(),正常
44 String[] strings = { "aa", "bb", "cc" };
45 List stringList = Arrays.asList(strings);
46 System.out.print("1、String类型数组使用asList(),正常: ");
47 for (String str : stringList) {
48 System.out.print(str + " ");
49 }
50 System.out.println();
51
52 // 2、对象类型(Integer)的数组使用asList(),正常
53 Integer[] integers = new Integer[] { 1, 2, 3 };
54 List integerList = Arrays.asList(integers);
55 System.out.print("2、对象类型的数组使用asList(),正常: ");
56 for (int i : integerList) {
57 System.out.print(i + " ");
58 }
59 System.out.println();
60
61 // 3、基本数据类型的数组使用asList(),出错
62 int[] ints = new int[] { 1, 2, 3 };
63 List intList = Arrays.asList(ints);
64 System.out.print("3、基本数据类型的数组使用asList(),出错(输出的是一个引用,把ints当成一个元素了):");
65 for (Object o : intList) {
66 System.out.print(o.toString());
67 }
68 System.out.println();
69
70 System.out.print(" " + "这样遍历才能正确输出:");
71 int[] ints1 = (int[]) intList.get(0);
72 for (int i : ints1) {
73 System.out.print(i + " ");
74 }
75 System.out.println();
76
77 // 4、当更新数组或者List,另一个将自动获得更新
78 System.out.print("4、当更新数组或者List,另一个将自动获得更新: ");
79 integerList.set(0, 5);
80 for (Object o : integerList) {
81 System.out.print(o + " ");
82 }
83 for (Object o : integers) {
84 System.out.print(o + " ");
85 }
86 System.out.println();
87
88 }
89 }
四、数组的分类
一维数组
一维数组的声明方式有2种:
- 格式一:数组元素类型 数组名[ ]; 即type var[ ];
- 格式二:数组元素类型[ ] 数组名; 即type[ ] var;
- 格式二声明数组的方法与C#上声明一维数组的方法一样。
例如:int
a1[ ]; int
[ ] a2;
double
b[ ];
person
[ ] p1; String
s1[ ];
注意:JAVA语言中声明数组时不能指定其长度(数组中的元素个数)
如:int
a[5]; 这样声明一维数组是非法的。
数组的模型
- 一维数组:一维数组就是一行,一行小格。
- 二维数组:二维数组就是一行加一列组成的一个平面分成的小格,有行有列。
- 三维数组:三维数组就是一个立方体。
- 人类对最多认识到三维空间。
数组对象的创建
JAVA中使用关键字new
创建数组对象。
格式为:数组名 = new
数组元素的类型[数组元素的个数]
例如:
元素为引用数据类型的数组
注意:元素为引用数据类型的数组中的每一个元素都需要实例化。
例如:
class Date{
int year; int moth; int day;
Date(int y; int m, int d){
year=y ;
month=m ;
day=d ;
}
}
数组的初始化
- 1.动态初始化
数组定义与为数组元素分配空间和赋值的操作分开进行。
例如:
查看代码
public class Test{
public static void main(String args[ ]){
int a[ ]; //定义数组,即声明一个int类型的数组a[ ]
a=new int[3]; //给数组元素分配内存空间。
a[0]=3; a[1]=9; a[2]=8; //给数组元素赋值。
Date days[ ];
days=new Date[3];
days[0]=new Date(1, 4, 2004);
days[1]=new Date(2, 4, 2004);
days[2]=new Date(3, 4, 2004);
}
}
class Date{
int year, month, day;
Date(int y, int m, int d){
year = y ;
month = m ;
day = d ;
}
}
- 2.静态初始化
在定义数组的同时就为数组元素分配空间并赋值。
例如:
查看代码
puclic class Test{
public static void main(String args[ ]){
int a[ ] = { 3, 9, 8}; //在定义数组的同时给数组分配空间并赋值。
Date days[ ] = {
new Date(1, 4, 2004),
new Date(2 ,4 ,2004),
new Date(3 ,4, 2004)
};
}
}
class Date{
int year, month, day;
Date(int y, int m, int d){
year = y ;
month = m ;
day = d ;
}
}
数组元素的默认初始化.
-
数组是引用类型,它的元素相当于类的成员变量,因此给数组分配内存空间后,每个元素也被按照成员变量的规则被隐式初始化。
查看代码
public class Test{ public static void main(String args[ ]){ int a[ ] = new int[5]; Date[ ] days=new Date[3]; System.out.println(a[3]); System.out.println(days[2]); } } class Date{ int year, month, day; Date(int y, int m, int d){ year = y ; month = m ; day = d ; } } /**输出结果 System.out.println(a[3]); 打印出来的结果是:0。 System.out.println(days[2]); 打印出来的结果是:null(空) */
数组元素的引用
定义并用运算符new为之分配内存空间后,才可以引用数组中的每个元素,数组元素的引用方式为:arrayName[index]
, index
为数组元素下标,可以是整型常量或整型表达式。如:a[3]
, b[i]
, c[6*i]
。
数组元素下标从0开始;长度为n的数组的合法下标取值范围为0 ~ n—1。
每个数组都有一个属性length
指明它的长度,例如:a.length
的值为数组a的长度(元素个数)。
二维数组
格式1
/*
二维数组:就是元素为一维数组的一个数组。
格式1:
数据类型[][] 数组名 = new 数据类型[m][n];
m:表示这个二维数组有多少个一维数组。
n:表示每一个一维数组的元素有多少个。
注意:
A:以下格式也可以表示二维数组
a:数据类型 数组名[][] = new 数据类型[m][n];
b:数据类型[] 数组名[] = new 数据类型[m][n];
B:注意下面定义的区别
int x;
int y;
int x,y;
int[] x;
int[] y[];
int[] x,y[];//这个x是一维数组,y是二维数组
*/
class Array2Demo {
public static void main(String[] args) {
//定义一个二维数组
int[][] arr = new int[3][2];
//定义了一个二维数组arr
//这个二维数组有3个一维数组的元素
//每一个一维数组有2个元素
//输出二维数组名称
System.out.println(arr); //地址值 [[I@175078b
//输出二维数组的第一个元素一维数组的名称
System.out.println(arr[0]); //地址值 [I@42552c
System.out.println(arr[1]); //地址值 [I@e5bbd6
System.out.println(arr[2]); //地址值 [I@8ee016
//输出二维数组的元素
System.out.println(arr[0][0]); //0
System.out.println(arr[0][1]); //0
}
}
格式1:内存图解
格式2
/*
格式2:
数据类型[][] 数组名 = new 数据类型[m][];
m:表示这个二维数组有多少个一维数组。
列数没有给出,可以动态的给。这一次是一个变化的列数。
*/
class Array2Demo2 {
public static void main(String[] args) {
//定义数组
int[][] arr = new int[3][];
System.out.println(arr); //[[I@175078b
System.out.println(arr[0]); //null
System.out.println(arr[1]); //null
System.out.println(arr[2]); //null
//动态的为每一个一维数组分配空间
arr[0] = new int[2];
arr[1] = new int[3];
arr[2] = new int[1];
System.out.println(arr[0]); //[I@42552c
System.out.println(arr[1]); //[I@e5bbd6
System.out.println(arr[2]); //[I@8ee016
System.out.println(arr[0][0]); //0
System.out.println(arr[0][1]); //0
//ArrayIndexOutOfBoundsException
//System.out.println(arr[0][2]); //错误
arr[1][0] = 100;
arr[1][2] = 200;
}
}
格式2: 内存图解
格式3
/*
格式3:
基本格式:
数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}};
简化版格式:
数据类型[][] 数组名 = {{元素1,元素2...},{元素1,元素2...},{元素1,元素2...}};
举例:
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
int[][] arr = {{1,2,3},{4,5},{6}};
*/
class Array2Demo3 {
public static void main(String[] args) {
//定义数组
int[][] arr = {{1,2,3},{4,5},{6}};
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[0][0]); //1
System.out.println(arr[1][0]); //4
System.out.println(arr[2][0]); //6
System.out.println(arr[0][1]); //2
System.out.println(arr[1][1]); //5
//越界
System.out.println(arr[2][1]); //错误
}
}
格式3: 内存图解
遍历二维数组
/*
需求:二维数组遍历
外循环控制的是二维数组的长度,其实就是一维数组的个数。
内循环控制的是一维数组的长度。
*/
class Array2Test {
public static void main(String[] args) {
//定义一个二维数组
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
//用方法改进
//调用方法
printArray2(arr);
}
/*
需求:遍历二维数组
两个明确:
返回值类型:void
参数列表:int[][] arr
*/
public static void printArray2(int[][] arr) {
for(int x=0; x<arr.length; x++) {
for(int y=0; y<arr[x].length; y++) {
System.out.print(arr[x][y]+" ");
}
System.out.println();
}
}
}
二维数组求和
/*
公司年销售额求和
某公司按照季度和月份统计的数据如下:单位(万元)
第一季度:22,66,44
第二季度:77,33,88
第三季度:25,45,65
第四季度:11,66,99
分析:
A:把题目的数据用二维数组来表示
int[][] arr = {{22,66,44},{77,33,88},{25,45,65},{11,66,99}};
B:如何求和呢?
求和其实就是获取到每一个元素,然后累加即可。
C:定义一个求和变量sum,初始化值是0。
D:通过遍历就可以得到每一个二维数组的元素。
E:把元素累加即可。
F:最后输出sum,就是结果。
*/
class Array2Test2 {
public static void main(String[] args) {
//把题目的数据用二维数组来表示
int[][] arr = {{22,66,44},{77,33,88},{25,45,65},{11,66,99}};
//定义一个求和变量sum,初始化值是0。
int sum = 0;
//通过遍历就可以得到每一个二维数组的元素。
for(int x=0; x<arr.length; x++) {
for(int y=0; y<arr[x].length; y++) {
//把元素累加即可。
sum += arr[x][y];
}
}
//最后输出sum,就是结果。
System.out.println("一年的销售额为:"+sum+"万元");
}
}
二维数组输出杨辉三角:打印杨辉三角形(行数可以键盘录入)
/*
需求:打印杨辉三角形(行数可以键盘录入)
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
分析:看这种图像的规律
A:任何一行的第一列和最后一列都是1
B:从第三行开始,每一个数据是它上一行的前一列和它上一行的本列之和。
步骤:
A:首先定义一个二维数组。行数如果是n,我们把列数也先定义为n。
这个n的数据来自于键盘录入。
B:给这个二维数组任何一行的第一列和最后一列赋值为1
C:按照规律给其他元素赋值
从第三行开始,每一个数据是它上一行的前一列和它上一行的本列之和。
D:遍历这个二维数组。
*/
import java.util.Scanner;
class Array2Test3 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
//这个n的数据来自于键盘录入。
System.out.println("请输入一个数据:");
int n = sc.nextInt();
//定义二维数组
int[][] arr = new int[n][n];
//给这个二维数组任何一行的第一列和最后一列赋值为1
for(int x=0; x<arr.length; x++) {
arr[x][0] = 1; //任何一行第1列
arr[x][x] = 1; //任何一行的最后1列
}
//按照规律给其他元素赋值
//从第三行开始,每一个数据是它上一行的前一列和它上一行的本列之和。
for(int x=2; x<arr.length; x++) {
//这里如果y<=x是有个小问题的,就是最后一列的问题
//所以这里要减去1
//并且y也应该从1开始,因为第一列也是有值了
for(int y=1; y<=x-1; y++) {
//每一个数据是它上一行的前一列和它上一行的本列之和。
arr[x][y] = arr[x-1][y-1] + arr[x-1][y];
}
}
//这个时候,要注意了,内循环的变化必须和曾经讲过的九九乘法表类似
for(int x=0; x<arr.length; x++) {
for(int y=0; y<=x; y++) {
System.out.print(arr[x][y]+" ");
}
System.out.println();
}
}
}