- 数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名称命名,并通过编号的方式对这些数据进行统一管理。
- 数组的常见概念
1)数组名
2)下标(或索引)
3)元素
4)数组的长度 - 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
- 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
- 数组的长度一旦确定,就不能修改。
- 我们可以通过下标(索引的方式)调用指定位置的元素,速度很快。
- 数组的分类
1)按照维度:一维数组、二维数组、三维数组、...
2)按照元素的数据类型分:基本数据类型元素的数组、引用数据类型元素的数据(即对象数组)
/*
一维数组的使用:
1.一维数组的声明和初始化
2.调用数组指定位置的元素
3.获取数组的长度
4.遍历数组
5.数组元素的默认初始化值
6.数组的内存解析
*/
public class ArrayTest {
public static void main(String[] args) {
//1.一维数组的声明和初始化
//1.1 静态初始化:数组的初始化和数组元素的赋值操作同时进行
int[] ids = new int[]{1001,1002,1003,1004};
//1.2 动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];
//2.调用数组指定位置的元素:通过数组的下标进行赋值
//数组的下标从0开始,到数组的长度-1结束
names[0] = "张三";
names[1] = "李四";
names[2] = "王五";
names[3] = "赵六";
names[4] = "孙七";
//3.获取数组的长度:属性:length
System.out.println(names.length);
//4.遍历数组
for(int i = 0;i < names.length;i++) {
System.out.println(names[i]);
}
//5.数组元素的默认初始化值
//整型数组元素:默认值为0
//浮点型数组元素:默认值为0.0
//char型数组元素:默认值为0或'\u000'
//boolean型数组元素:默认值为false
//引用数据类型数组元素:默认值为null
}
}
-
常用内存结构解析
-
一维数组内存结构解析
- Java语言中提供了支持多维数组的语法。
- 如果说可以把一维数组当成几何中的线性图形,那么二维数组就相当于是一个表格,像Excel表格一样。
- 对于二维数组的理解,我们可以看作是一维数组array1又作为另一个一维数组array2的元素而存在。其实,从数组底层的运行机制来看,其实并没有多维数组。
/*
二维数组的理解:
对于二维数组的理解,我们可以看作是一维数组array1又作为另一个一维数组array2的元素而存在。
其实,从数组底层的运行机制来看,其实并没有多维数组。
二维数组的使用:
1.二维数组的声明和初始化
2.调用数组指定位置的元素
3.获取数组的长度
4.遍历数组
5.数组元素的默认初始化值
规定:二维数组分为内层元素和外层元素
int[][] array = new int[4][3];
外层元素:array[0]、array[1]等
内层元素:array[0][0]、array[1][2]等
针对于初始化方式一:比如:int[][] array = new int[4][3];
外层元素的初始值为地址值,内层元素的初始值与一维元素的初始值相同
针对于初始化方式二:比如:int[][] array = new int[3][];
外层元素的初始值为null,内层元素的初始值会报NullPointerException
6.数组的内存解析
*/
public class ArrayTest2 {
public static void main(String[] args) {
//一维数组的初始化
int[] array1 = new int[]{1,2,3,4,5};
//二维数组的静态初始化
int[][] array2 = new int[][]{{1,2,3},{4,5},{6,7,8}};
//二维数组的动态初始化
//方式一:
String[][] array3 = new String[3][2];
//方式二:
String[][] array4 = new String[3][];
//2.调用数组指定位置的元素
System.out.println(array2[0][1]); //结果为2
System.out.println(array3[1][1]); //结果为null
array4[1] = new String[4];//对二维数组进行初始化
System.out.println(array4[1][0]); //如果未初始化,会报NullPointerException
//3.获取数组的长度
System.out.println(array2.length); //结果为3
System.out.println(array2[0].length); //结果为3
System.out.println(array2[1].length); //结果为2
System.out.println(array2[2].length); //结果为3
//4.遍历二维数组
for (int i = 0;i < array2.length;i++) {
for(int j = 0;j < array2[i].length;j++) {
System.out.print(array2[i][j] + "\t");
}
System.out.println();
}
//5.数组元素的默认初始化值
int[][] array5 = new int[4][3];
System.out.println(array5[0]); //地址值:[I@1540e19d
System.out.println(array5[0][0]); //0
System.out.println(array5); //地址值:[[I@677327b6
double[][] array6 = new double[3][];
System.out.println(array6[1]); //null
//System.out.println(array6[1]); //NullPointerException
}
}
- 二维数组内存结构的解析
4.1 数组元素的赋值(杨辉三角、回形数等)
4.2 求数值型数组中元素的最大值、最小值、平均数、总和等
/*
算法的考查:求数值型数组中元素的最大值、最小值、平均数、总和等
要求:定义一个int型的一维数组,包含10个元素,分别赋一个随机整数
然后求出所有元素的最大值、最小值、平均值和总和,并输出出来
所有随机值都是两位数
[10-99]
公式:(int)(Math.random() * (99-10+1) + 10)
*/
public class ArrayTest {
public static void main(String[] args) {
//数组的初始化
int[] array = new int[10];
//给数组元素随机赋值
for(int i = 0;i < array.length;i++) {
array[i] = (int)(Math.random() * (99-10+1) + 10);
}
//数组元素的遍历
for(int i = 0;i < array.length;i++) {
System.out.print(array[i] + "\t");
}
System.out.println();
//求数组元素的最大值
int maxValue = array[0];
for(int i = 1;i < array.length;i++) {
if(maxValue < array[i]) {
maxValue = array[i];
}
}
System.out.println("最大值为:" + maxValue);
//求数组元素的最小值
int minValue = array[0];
for(int i = 1;i < array.length;i++) {
if(minValue > array[i]) {
minValue = array[i];
}
}
System.out.println("最小值为:" + minValue);
//求数组元素的总和
int sum = 0;
for (int i = 0;i < array.length;i++) {
sum = sum + array[i];
}
System.out.println("总和为:" + sum);
//求数组元素的平均值
double avgValue = sum / array.length;
System.out.println("平均值为:" + avgValue);
}
}
4.3 数组的复制、反转、查找(线性查找、二分查找)
/*
算法的考查:数组的复制、反转
*/
public class ArrayTest1 {
public static void main(String[] args) {
String[] array1 = new String[]{"DD","MM","GG","JJ","AA"};
//数组的复制
String[] array2 = new String[array1.length];
for(int i = 0;i < array1.length;i++) {
array2[i] = array1[i];
}
//数组元素的遍历
for(int i = 0;i < array2.length;i++) {
System.out.print(array2[i] + "\t");
}
System.out.println();
//数组元素的反转
for(int i = 0;i < array1.length / 2;i++) {
String temp = array1[i];
array1[i] = array1[array1.length - i - 1];
array1[array1.length - i - 1] = temp;
}
for(int i = 0;i < array1.length;i++) {
System.out.print(array1[i] + "\t");
}
}
}
/*
数组元素的查找:线性查找和二分查找
*/
public class ArrayTest2 {
public static void main(String[] args) {
String[] array1 = new String[]{"DD","MM","GG","JJ","AA"};
String dest = "BB";
boolean isFlag = true;
//线性查找
for(int i = 0;i < array1.length;i++) {
if(dest.equals(array1[i])) {
System.out.println("找到了指定的元素,位置为:" + i);
isFlag = false;
break;
}
}
if(isFlag) {
System.out.println("很遗憾,没有找到指定的元素");
}
//二分查找
//要求查找的数组元素必须有序
int[] array2 = new int[]{-2,8,25,46,78,96,103};
int head = 0;//头索引
int end = array2.length - 1;
int dest1 = 25;
boolean isFlag1 = true;
while(head <= end) {
int middle = (head + end) / 2;
if(dest1 == array2[middle]) {
System.out.println("找到了指定的元素,位置为:" + middle);
isFlag1 = false;
break;
} else {
//当目标元素值大于中间索引元素的值
if(dest1 > array2[middle]) {
//head索引往后移
head = middle + 1;
//当目标元素值小于中间索引元素的值
} else {
//end往前移
end = middle - 1;
}
}
}
if(isFlag1) {
System.out.println("很遗憾,没有找到指定的元素");
}
}
}
4.4 数组元素的排序算法
-
排序:假设含有n个记录的序列为{R1,R2,...,Rn},其对应的关键字序列为{K1,K2,...,Kn}。给这些记录重新排序为{Ri1,Ri2,...,Rin},使用相应的关键字值条件满足Ki1<=Ki2<=...<=Kin,这样的一种操作称为排序。
通常来说,排序的目的是快速查找
-
衡量排序算法的优劣:
1.时间复杂度:分析关键字的比较次数和记录的移动次数
2.空间复杂度:分析排序算法中需要多少辅助空间
3.稳定性:如果两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的. -
排序算法的分类:
1.内部排序
2.外部排序 -
十大内部排序算法:
- 选择排序
1.直接选择排序、堆排序 - 交换排序
1.冒泡排序和快速排序 - 插入排序
1.直接插入排序、折半插入排序、Shell排序 - 归并排序
- 桶式排序
- 基数排序
- 选择排序
/*
冒泡排序的实现:
*/
public class BubbleSortTest {
public static void main(String[] args) {
int[] array = new int[]{43,32,65,-8,12,-7,0,9,98};
//控制轮数
for(int i = 0;i < array.length - 1;i++) {
//控制每一轮的次数
for(int j = 0;j < array.length - 1 - i;j++) {
if(array[j] > array[j+1]) {
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
//遍历数组元素
for(int i = 0;i < array.length;i++) {
System.out.print(array[i] + "\t");
}
}
}
5.Arrays工具类的使用
java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法。
/*
数组工具类的使用:
*/
public class ArraysTest {
public static void main(String[] args) {
//1.判断两个数组是否相等
int[] array1 = new int[]{1,2,3,4};
int[] array2 = new int[]{1,3,2,4};
int[] array3 = new int[]{2,6,15,19,30,36,45,60};
boolean b = Arrays.equals(array1,array2);
System.out.println(b);
//2.输出数组信息
String s = Arrays.toString(array1);
System.out.println(s);
//3.将指定值填充到数组当中
Arrays.fill(array1,10);
System.out.println(Arrays.toString(array1));
//4.对数组元素进行排序
Arrays.sort(array2);
System.out.println(Arrays.toString(array2));
//5.二分查找
int count = Arrays.binarySearch(array3,36);
System.out.println(count);
}
}