数组
1.数组定义:
数组是最简单的数据结构,数组是相同类型的数据的有序集合。数组描述的是相同类型的若干数据,按照一定的先后次序排列组合而来,其中,每一个数组称作一个数组元素,每个数组元素可以通过一个下标来访问。
2.数组声明和创建
首先必须声明数组变量才能在程序中使用。其语法结构如下:
dataType[] arrayRevar;//java首选的数组声明方式。
dataType arrayRevar[];//效果是相同的但是不是首选的方法。
以上两种方式均可以声明一个数组,但是第一种是首选,第二种是java发展早期为了使c、c++语言使用者更适应而使用的。
java语言使用new操作符来创建数组。其语法结构如下:
dataType[] arrayRevar = new dataType[arraySize];
注:数组的元素是通过索引访问的,数组索引从零开始。
声明和创建也可以放在一起,例:
int[] nums = new int [10];//声明并创建一个有十个元素的数组。
3.拓展
Java内存是分为堆和栈的。
栈是用来存放基本变量类型(会包含这个基本类型的具体数值)和引用对象的变量(会存放这个引用在堆里面的地址)的。
堆需要注意的点:
- 存放new的对象和数组;可以被所有线程共享,不会存放别的对象。
- 创建数组时new出,相当于在堆里开辟了一个小空间。
- 当你取得值下标不在你创建的数组下标范围内,会出现数组下标越界的情况。
数组的声明和创建我们就可以理解为,当我们声明数组时,栈中就会存入一个地址,这个地址对应这个被声明的数组,此时的数组是没有任何东西的。而创建时,则会在堆中开辟一个小空间用来存放数组元素。
需要注意的是由于数组下标时是从零开始,因此取最大值得坐标是元素数量-1(也是数组长度-1),新手在数组上面遇到下标越界就要考虑是不是因为自己取值时下标取错了。数组的合法边界为[0,array.length-1](array.length为数组的长度)。报错信息为:ArrayIndexOutOfBoundException
4.数组初始化
-
静态初始化:
int [] a = {1,2,3};//静态初始化要注意,一旦定义就不可以改变数组了
-
动态初始化:
int[] a = new int[2];//声明创建一个长度为2的数组 a[0] = 1;//数组第一个元素值为1 a[1] = 2;//数组第二个元素值为2
-
数组的默认初始化
数组是引用类型,他的元素相当于类的实例变量,因此数组的一经分配空间其中的每个元素也按照实例变量同样的方式被隐式初始化。
5.数组的使用及for-each循环
- 打印数组元素
//生命创建一个名为arrays的数组
int [] arrays = {1,2,3,4,5};
//使用普通for循环打印数组的全部元素
for (int i = 0; i < arrays.length; i++) {
System.out.println(arrays[i]);
}
//使用for-each循环打印数组的全部元素
for (int array : arrays) {
System.out.println(array);
}
注:for-each循环的优势在于,当数组需要打印输出时,可以省去下标,但是其劣势在于不适合操作某一项元素。
- 将数组作为返回值(反转数组方法为例)
public class Demo {
public static void main(String[] args) {
int [] arrays = {1,2,3,4,5};
//声明一个数组使其等于反转过后的arrays数组
int [] x = reverse(arrays);
//打印反转后的arrays数组
printTest(x);
}
//遍历数组并输出值得方法
public static void printTest(int[] test){
for (int i = 0; i < test.length; i++) {
System.out.print(test[i]+" ");
}
}
//反转数组的方法
public static int[] reverse(int[] array){
int [] result = new int[array.length];
for (int i = 0,j = result.length-1; i < result.length; i++,j--) {
result[j] = array[i];
}
return result;
}
}
6.多维数组
多维数组可以看成是数组的数组,如二维数组就是元素都为一维数组的数组。
如:int a [][] = new int [2] [5]表示一个二行五列的数组。
平时二维数组基本够用但是需要多理解多维数组如何用、写、读值和取值。
二维数组使用示例:
public class Demo {
public static void main(String[] args) {
//定义一个二维数组
int[][] arrays = {{1,2},{3,4},{5,6},{7,8}};
//输出数组的长度
System.out.println(arrays.length);
//输出某个内部数组的长度,以内部第二个数组为例
System.out.println(arrays[1].length);
//输出某个元素,以第三个数组第二个元素为例
System.out.println(arrays[2][1]);
//输出某个数组,以第一个数组为例
printTest(arrays[0]);
//遍历多维数组
for (int i = 0; i < arrays.length; i++) {
for (int j = 0; j < arrays[i].length; j++) {
System.out.println(arrays[i][j]);
}
}
}
//遍历数组并输出元素得方法
public static void printTest(int[] test){
for (int i = 0; i < test.length; i++) {
System.out.print(test[i]+" ");
}
}
}
7.Arrays类
数组的工具类java.util.Arrays
由于数组对象本省并没有什么方法可以供我们调用,但API中提供了一个工具类Array供我们使用,从而可以对数据对象进行一些基本操作。Arrays类中的方法都是static修饰的,因此我们使用时都是可以使用类名进行调用的而不需要使用对象来调用。
Arrays常用功能:
- fill:给数组赋值
- sort:给数组按升序排序
- equals:用于比较数组中元素是否相等
- binaraySearch:此方法能对排序好的数组进行二分查找
import java.util.Arrays;
public class Demo {
public static void main(String[] args) {
int[] a = {32,15,65,16,31,61,63};
//我们发现打印数组出来的并不是数组,而是一串数字
System.out.println(a);
//我们可以用Arrays中的toString方法打印数组元素
System.out.println(Arrays.toString(a));
//输出升序排好的数组
Arrays.sort(a);
System.out.println(Arrays.toString(a));
//填充数组,所有元素填充为零
Arrays.fill(a,0);
System.out.println(a);
//填充数组,将第三个元素到第五个元素之间的元素填充为5
Arrays.fill(a,2,4,5);
System.out.println(Arrays.toString(a));
}
}
8.冒泡排序
是八大排序之一,用于将数组的值进行排序
import java.util.Arrays;
public class Demo {
public static void main(String[] args) {
//冒泡排序示例:声明创建一个数组并调用我们写的方法
int [] a = {54,12,68,78,36,2,63,20};
sort(a);
//冒泡排序老师写的方法
int [] b = sorto1(a);
System.out.println(Arrays.toString(b));
}
//自己的思路
public static void sort(int array[]){
//定义一个长度和要比较的数组的空数组。
int [] x = new int[array.length];
x.equals(array);
//定义一个变量用于交换时充当中间变量
int m = 0;
//外部循环,控制总共比较几轮,以及控制给空数组辅助多少个元素
for (int i = 0; i < array.length; i++) {
//内部循环控制每一轮循环要比较的次数
for (int j = 0; j < array.length-1; j++) {
if(array[j] > array[j+1]){
m = array[j];
array[j] = array[j+1];
array[j+1] = m;
}
}
//每轮内部循环会比较出一个最大的值将最大值倒叙赋值给x数组
x[array.length-i-1] = array[array.length-i-1];
}
//输出按照从小到大排序好的数组
System.out.println(Arrays.toString(x));
}
//老师的方法
public static int[] sorto1(int[] array){
//定义中间变量用于交换值
int temp = 0;
for (int i = 0; i < array.length; i++) {
//优化部分,用于避免无效的比较
boolean flag = false;
for (int j = 0; j < array.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;
}
}
return array;
}
}
自己写完再看的老师的方法,最后发现我的方法声明创建空数组是多此一举的行为,不过好在自己至少是把功能实现了。
9.稀疏数组
有时候我们会遇到数组特别大,但是有效数字却相对较少的情况,例如,我们想记录五子棋盘上的棋局,但是当棋子比较少的时候,就会记录很多没有意义的数据,因此产生了稀疏数组这种数据结构。
稀疏数组结构只记录原数组共有多少行,多少列,共有多少个有效元素,以及每个元素的坐标和元素值。(简单来讲就是我们使用小的数组来通过记录坐标和有效元素值的方式将数组规模大大的缩减。)
其结构如下:
[行] [列] [值]
[0] (原数组的行,列以及有效元素的数量)
[1] x1 y1 z1
[2] x2 y2 z2
… … … …
(也由此得知,稀疏数组呢必定为一个n行,3列的数组,第一行记录的是原数组总行数、总列数、有效元素的总数量m,因此n=m+1,即数组有m+1行)
以存储五子棋游戏某一棋局为例:
public class Demo {
public static void main(String[] args) {
//创建一个11行,11列的二维数组保存棋盘,规定0为空棋子,1是黑棋,2是白棋。
int[][] array1 = new int[11][11];
//将第二行第三列记录一颗黑棋,第三行第四列记录一颗白棋
array1[1][2] = 1;
array1[2][3] = 2;
//输出原数组
System.out.println("输出原数组:");
for (int[] ints : array1) {
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++) {
//如果某一项元素不等于零,那么sum加一
if(array1[i][j] != 0){
sum++;
}
}
}
System.out.println("有效的个数为:"+sum);
//创建一个稀疏数组
int [][] array2 = new int[sum+1][3];
array2[0][0] = 11;
array2[0][1] = 11;
array2[0][2] = sum;
//遍历原二维数组,将有效值存放到稀疏数组
//定义一个变量用于记录有效值的横坐标,因为有几个有效元素,就有多少行有效元素的坐标
int count = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
if (array1[i][j] != 0){
count++;
//分别将有效值的坐标和值赋值给稀疏数组。
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j];
}
}
}
//输出稀疏数组
System.out.println("输出稀疏数组:");
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i][0]+"\t"+array2[i][1]+"\t"+array2[i][2]);
}
//稀疏数组的还原
//思路,因为我们有坐标值和元素值,那么我们将元素值对应坐标赋值到一个规模与原数组相等的空数组中即可,因为未赋值的地方默认值为零
System.out.println("还原稀疏数组:");
//定义一个稀疏数组记录的几行几列的空数组;
int [][] array3 = new int[array2[0][0]][array2[0][1]];
//给这个空数组赋值原数组的有效值,从稀疏数组的第二行开始
for (int i = 1; i < array2.length; i++) {
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}
//输出还原后的数组
System.out.println("输出还原后的数组:");
for (int[] ints : array3) {
for (int anInt : ints) {
System.out.print(anInt+"\t");
}
System.out.println();
}
}
}
OKOK,那么以上就是关于数组的一些基础知识了,也就意味着java基础部分就要结束了,即将面对面向对象部分,希望自己继续加油!
冲冲冲!
如果以上内容有哪里说得不准确或者不到位的话,还请小伙伴们批评指正!
附上学习网站学相伴https://www.kuangstudy.com/