数组概述
数组声明创建
数组使用
多维数组
Arrays类
稀疏数组
1. 数组介绍
-
数组是相同类型数据的有序集合
-
数组描述相同类型对象的若干个数据,按照一定的先后次序排列组合而成
-
其中,每一个数据称为一个数组元素,可以通过下标来访问它们
2. 数组声明创建及初始化
-
第一步声明数组变量,才能在程序中使用数组
dataType[] arrayName;
//如:int[] nums; -
第二步使用new操作符来创建数组
arrayName = new dataType[arraySize];
//如 nums = new int[10]; -
第三步给数组中的元素赋值(没有被赋值为默认值,0 或者 null)
nums[0] = 1;
num[1] = 2;
num[2] = 3;
... -
声明数组和创建数组可以同时完成
int[] nums = new int[10];
int[] nums = {1,2,3,4,5}
//常用这两种写法同时完成 -
数组三种初始化
-
静态初始化
int[] a = {1,2,3,4,5};
String[] str = {"this", "is", "hello", "world"}; -
动态初始化
int[] a = new int[10];
nums[0] = 1;
num[1] = 2;
num[2] = 3;
... -
默认初始化
-
数组是引用类型,它的元素相当于类的实例变量,因此数组一旦创建,就会被分配好空间,其中每个元素就会按照实例变量同样的方法被隐式初始化。即没有被初始化的值默认为 0 或者 null,false。
-
-
-
数组的四个基本特点
-
其长度是确定的。一旦被创建,它的大小不可以改变。
-
数组里所有元素必须是相同类型
-
数组元素可以是任何数据类型(基本类型,引用类型)
-
数组变量属于引用类型,数组本身就是对象,里面每个元素相当于该对象的成员。Java中对象是在堆中的。
-
3. 数组使用及内存分析
-
数组使用方法
-
for - each 循环
-
数组作方法引入参
-
数组作返回值
注意定义类型 + 变量名
-
-
数组边界
-
下标合法区间:[0,length-1], 如果越界就会报错。其中 ArrayName.length 就是该数组长度
-
ArrayIndexOutOfBoundsException : 数组下标越界异常!
-
-
Java内存分析
-
堆
-
存放new的对象和数组
-
可以被所有的线程共享,不会存放别的对象引用
-
-
栈
-
存放基本数据类型(包括具体值)
-
引用对象的变量(包括存放引用在堆里面的具体地址)
-
-
方法区
-
可以被所以线程共享
-
包含了所有的class和static变量
-
-
4. 多维数组
-
Java使用数组一般不会超过二维数组,二维数组就是特殊的一维数组,每一个元素都是一个一维数组
-
二维数组创建
int a[][] = new int[2][4];
-
多维数组的使用
// 打印二维数组
int[][] array = {{1,2},{2,3},{3,4}};
for(int i=0;i<array.length;i++){
for(int j=0;j<array[i].length;j++){
System.out.print(array[i][j]+" ");
}
}
5. Arrays类
-
数组工具类 java.util.Arrays
-
数组对象本身没有声明方法供我们调用,但API中提供了一个工具类Arrays给我们使用,从而完成一些对数组的操作
-
查看 JDK 帮助文档 或者 Arrays类方法的源代码 ( 学习编程思路)
-
Arrays 中的方法都是 static 修饰的静态方法,在使用的时候可以直接使用类名进行调用。
-
常用功能
-
给数组赋值:fill 方法
-
对数字排序:sort方法(升序)
-
比较数组:equals方法(比较数组中元素是否相等)
-
查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作
-
6.冒泡排序
-
冒泡排序式最出名的排序算法,总共有八大排序
-
冒泡排序很简单,两层循环,外层冒泡轮数,里层一次比较。
-
我们看到嵌套循环,就应该立马得出这个算法的时间复杂度O(n^2)
int temp =0; // 临时变量,用于交换
// 外层循环,判断我们要走多少次
for(int i=0;i<array.length;i++){
// 内层循环,比较相邻的数的大小,并实现交换位置功能
for(int j=0 ; j< array[i].length-1-i; j++){
if(array[j+1]<array[j]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
System.out.println(Arrays.toString(array));
} -
思考一些,如何优化?
int temp =0; // 临时变量,用于交换
// 外层循环,判断我们要走多少次
for(int i=0;i<array.length-1;i++){
// 通过flag标识来减少没有意义的比较
boolean flag = false;
// 内层循环,比较相邻的数的大小,并实现交换位置功能
for(int j=0 ; j< array[i].length-1-i; j++){
if(array[j+1]<array[j]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
flag = true;
}
if(flag == false){
// 如果没有进行数据交换就直接跳出循环
break;
}
}
System.out.println(Arrays.toString(array));
}
7. 稀疏数组(一种数据结构)
-
介绍
-
当一个数组中大部分元素为0,或者同一个值的数组时,就可以使用稀疏数组来保存该数组
-
稀疏数组的处理方法
-
记录数组一共几行几列,有多少个不同值
-
把具有不同值的元素的行和列及值记录在一个小规模的数组中
-
如同,左边为原始数组,右边为稀疏数组。
-
第0行记录了原始数组的行列数及有效值个数,其他行数记录了有效值的坐标和值的大小。(n行3列的形式)
-
-
-
示例
-
需求:编写五子棋游戏中,有存盘退出和续上盘的功能
-
分析问题:因为该二维数组的很多值默认为0,因此记录了许多没有意义的数据
-
解决:稀疏数组
package MethodArray.ArrayStudy;
public class ArrayTest_5 {
public static void main(String[] args) {
// 1. 创建一个二维数组11*11, 0:没有棋子, 1:黑棋, 2:白棋
int[][] array = new int[11][11];
array[1][2] = 1;
array[2][3] = 2;
// 输出原始的数组
System.out.println("输出原始的数组");
for (int[] ints : array) {
for (int anInt : ints) {
System.out.print(anInt + "\t");
}
System.out.println();
}
// 转化为稀疏数组来保存
int sum=0; // 获取有效值的个数
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if(array[i][j]!=0){
sum +=1 ;
}
}
}
System.out.println("有效值的个数为:" + sum);
// 1.稀疏数组是一个n行3列的二维数组,第一行三列分别 存储原数组 行列数 及 有效值个数。
// 2.其他的行数存储 有效值的 行列数 及其 值
// 3.创建一个稀疏数组
int[][] smallArray = new int[sum+1][3];
smallArray[0][0] = 11;
smallArray[0][1] = 11;
smallArray[0][2] = sum;
// 变量二维数组,将 非0 的值存放进去
int count = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
if(array[i][j]!=0){
smallArray[count+1][0] = i;
smallArray[count+1][1] = j;
smallArray[count+1][2] = array[i][j];
count+=1;
}
}
}
// 打印稀疏数组
System.out.println("输出稀疏数组");
for (int[] arr:smallArray){
for (int anInt:
-