一、引言
1.1 为什么使用数组
如何存储100名学生的成绩?
办法:使用变量存储,重复声明100个double类型变量即可。
缺点:麻烦,重复操作过多。
如何让100名学生成绩全部+1?
办法:100个变量重复相同操作,直至全部完毕。
缺点:无法进行统一的操作。
二、数组的概念
2.1 数组的概念
概念: 一组连续的存储空间,存储多个相同数据类型的值。
特点:
类型相同
长度固定
三、数组的声明与赋值
3.1 数组的创建
四、数组的组成
4.1 数组的组成
- 数组中的每个数据格被称为“数组元素”。
- 对每个元素进行赋值或取值的操作被称为“元素的访问”。
- 访问元素时,需要使用“下标”(从0开始,依次+1,自动生成)。
- 访问的语法:数组名[下标]; //例如 存:a[0]=10; 取:a[0];
4.3 注意下标的范围
- 有效下标范围:0 ~ 数组长度-1
- 访问无效下标,会导致数组下标越界
五、数组的遍历【重点】
5.1 数组的遍历
遍历:从头至尾,逐一对数组的每个元素进行访问。
5.2 数组的默认值
数组默认值:
整数:0
小数:0.0
字符:\u0000
布尔:false
其他:null
5.3 数组创建语法
- 先声明、再分配空间:
- 数据类型[] 数组名;
- 数组名 = new 数据类型[长度];
- 声明并分配空间:
- 数据类型[] 数组名 = new 数据类型[长度];
- 声明并赋值(繁):
- 数据类型[] 数组名 = new 数据类型[]{value1,value2,value3,…};
- 声明并赋值(简):
- 数据类型[] 数组名 = {value1,value2,value3,…}; (显示初始化,注意:不可换行)。
5.4 案例1
import java.util.Arrays;
public class Test1 {
public static void main(String[] args) {
int a = 60;
int b = 100;
int c = 80;
int d = 81;
int e = 100;
//1.数组是一个容器
//2. 数据类型相同 长度固定的
//3.第一种定义方式 最常用
int[] arrScore = new int[5];
// 第二种定义方式, 声明和初始化分开,可能会用
int[] arrScore1;
arrScore1 = new int[5];
//第三种定义方式 这种方式不用
int[] arrScore2 = new int[]{1,2,3,4,5};
//赋值 数据名[下标]
arrScore[0] = 60;
arrScore[1] = 100;
arrScore[2] = 80;
arrScore[3] = 81;
arrScore[4] = 120;
//查看数据方式一:
System.out.println("查看数据方式一:sout打印:");
System.out.println(arrScore[0]);
System.out.println(arrScore[1]);
System.out.println(arrScore[2]);
System.out.println(arrScore[3]);
System.out.println(arrScore[4]);
//循环打打印
//数组提供 长度值
int length = arrScore.length;
System.out.println(length);
System.out.println("查看数据方式二:循环打印:");
for(int i=0; i<length; i++) {
System.out.println(arrScore[i]);
}
//查看数据方式三: System.in
System.out.println("查看数据方式三:"+Arrays.toString(arrScore));
}
}
5.5课堂案例2
import java.util.Arrays;
public class Test2 {
public static void main(String[] args) {
//1.定义数组 数组类型[] 数组名称 = new 数组的类型[数组的长度];
int[] weight = new int[5];
//2.赋值
weight[0] = 110;
weight[1] = 140;
weight[2] = 130;
weight[3] = 160;
weight[4] = 170;
//3.查看数
System.out.println(Arrays.toString(weight));//[110, 140, 130, 160, 170]
System.out.print("[");
for(int i=0; i<weight.length; i++) {
//如果 i != (weight.length-1) 加,
if(i!=(weight.length-1)) {
System.out.print(weight[i]+",");
}else { //否则 不加
System.out.print(weight[i]);
}
}
System.out.print("]");
System.out.println();
//4.给每个人增重5公斤
for (int i=0; i<weight.length; i++) {
//改变所有值
//weight[i] = weight[i]+10;
//改变第三个值
if(i==2) {
weight[i] = weight[i]+10;
}
}
//5.再次打印:
System.out.println(Arrays.toString(weight));
//如果下标超了范围, 数组下标越界: Array Index OutOf Bounds Exception
System.out.println(weight[5]);
}
}
5.6课堂案例3
public class Test4 {
public static void main(String[] args) {
int heroLength = 5;
//1.定义数组
String[] arrHero = new String[heroLength];
//2.赋值
arrHero[0] = "李白";
arrHero[1] = "马可波罗";
arrHero[2] = "如花";
arrHero[3] = "西施";
arrHero[4] = "柳下惠";
//3.查看值
for (int i=0; i<arrHero.length; i++) {
System.out.print(arrHero[i]+" ");
}
System.out.println();
//4把如花赶紧让她走,换杨玉环
for (int i=0; i<arrHero.length; i++) {
if(i==2) {
arrHero[i] = "杨玉环";
}
}
System.out.println(Arrays.toString(arrHero));
}
}
六、数组的扩容
6.1 数组的扩容
创建数组时,必须显示指定长度,并在创建之后不可更改长度。
扩容的思路:
- 创建大于原数组长度的新数组。
- 将原数组中的元素依次复制到新数组中。
6.2 复制的方式
循环将原数组中所有元素逐一赋值给新数组
public class Test5 {
public static void main(String[] args) {
// 数组默认值:
// 整数:0
int[] arrInt = new int[5];
System.out.println("int[]的默认值:"+arrInt[4]);
// 小数:0.0
double[] arrdouble = new double[3];
System.out.println("double[]的默认值:"+arrdouble[2]);
// 布尔:false
boolean[] arrBoolean = new boolean[5];
System.out.println("boolean默认值:"+arrBoolean[4]);
// 其他:null
String[] arrStr = new String[5];
System.out.println("String默认值:"+arrStr[1]);
//char 默认的是空格
char[] arrChar = new char[1];
System.out.println("char[]默认值:="+arrChar[0]+"=");
String heroName = null;
System.out.println("heroName="+heroName);
System.out.println("--------------------------------");
String heroName1 = "";
System.out.println("heroName1="+heroName1);
System.out.println("--------------------------------");
String heroName2 = " ";
System.out.println("heroName2="+heroName2+"*");
System.out.println("--------------------------------");
}
}
System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度)
package com.qfedu;
import java.util.Arrays;
public class Test7Copy {
public static void main(String[] args) {
//System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度)。
String[] oldArr = new String[3];
oldArr[0] = "郭老师";
oldArr[1] = "如花";
oldArr[2] = "老八";
String[] newArr = new String[5];
//复制数组System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度)。
//两个起始位置说的是 下标,如果超了ArrayIndexOutOfBoundsException
System.arraycopy(oldArr,0,newArr,1,2);
//打印
System.out.println(Arrays.toString(oldArr));
System.out.println(Arrays.toString(newArr));
//复制数组System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度)。
// System.arraycopy(oldArr,0,newArr,4,2);
//把 oldArr --> newArr 复制所有元素
System.arraycopy(oldArr,0,newArr,0,oldArr.length);
System.out.println(Arrays.toString(oldArr));
System.out.println(Arrays.toString(newArr));
}
}
java.util.Arrays.copyOf(原数组, 新长度)
返回带有原值的新数组。
public class Test8Copy {
public static void main(String[] args) {
//System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度)。
String[] oldArr = new String[3];
oldArr[0] = "郭老师";
oldArr[1] = "如花";
oldArr[2] = "老八";
// java.util.Arrays.copyOf(原数组, 新长度)。
//不能指定超始位置
String[] newArr = Arrays.copyOf(oldArr, 2);
System.out.println(Arrays.toString(newArr));
}
}
6.3 地址替换
- 数组作为引用类型之一,其变量中存储的是数组的地址。
- 完成元素复制后,需将新数组地址,赋值给原变量进行替换。
public class Test9 {
public static void main(String[] args) {
int[] arrInt1 = new int[2];
int[] arrInt2 = new int[3];
arrInt1[0] = 1;
arrInt1[1] = 2;
arrInt2[0] = 3;
arrInt2[1] = 4;
arrInt2[2] = 5;
System.out.println(Arrays.toString(arrInt1));
System.out.println(Arrays.toString(arrInt2));
// arrInt1 指向 数组arrInt2的地址
arrInt1 = arrInt2;
System.out.println(Arrays.toString(arrInt1));
System.out.println(Arrays.toString(arrInt2));
//证明是同一个地址值 :
System.out.println(arrInt1==arrInt2); //返回结果是true
}
}
七、方法中数组类型的参数或者返回值
7.1 数组类型的参数
- 方法调用时,将oldArr中的地址赋值给newArr,此时二者指向同一个数组。
- newArr = oldArr这种写法
- 传递参数时:基本类型传递的是变量中的值;引用类型传递的是变量中的地址。
7.2 数组类型的返回值
调用数组类型返回值的方法时,方法执行后,返回的是数组的地址。
//1.基本数据类型的传递,是“值”的传递,一方改变,不会影响另一方
//2.引用数据类型的传递,是“地址”的传递,一方改变,会影响另一方
import java.util.Arrays;
public class Test10Method {
public static void main(String[] args) {
//1.定义
String[] arrHeroName = new String[3];
arrHeroName[0] = "貂蝉";
arrHeroName[1] = "如花";
arrHeroName[2] = "如花";
//2.调用方法
printArr(arrHeroName);
//加强for循环
printArr2(arrHeroName);
//返回值是数组类型的方法
String[] newArr = arrCopy(arrHeroName);
System.out.println(Arrays.toString(newArr));
}
//方法的功能: 传入一个字符串数组,并且进行打印
public static void printArr(String[] arr) {
//打印
for(int i=0; i<arr.length; i++) {
//如果里边有叫如花的,那就输出 请回头
if(arr[i].equals("如花")) {
System.out.println("如花请回头");
}
System.out.println(arr[i]+" ");
}
//只是查看
//System.out.println(Arrays.toString(arr));
}
// for的别外一种表现方式: 加强for循环
public static void printArr2(String[] arr) {
for (String s : arr) {
System.out.println(s);
}
// 0 - arr.length
//arr里边从下标0开始,合出每一个数组的元素,给了变量String s ,然后进行操作
/*for(int i =0; i<arr.length; i++) {
String s = arr[i];
}*/
}
//写一个方法 :需求: 传入一个数组,复制出一个两倍长的新数组,并组把旧数组中的值都放入新数组,把新数组返回
public static String[] arrCopy(String[] oldArr) {
//1.新建一个数组
String[] newArr = new String[oldArr.length*2];
//2.复制
System.arraycopy(oldArr,0,newArr,0,oldArr.length);
return newArr;
}
}
八、可变长参数
8.1 可变长参数
概念: 可接收多个同类型实参,个数不限,使用方式与数组相同。
语法: 数据类型… 形参名 //必须定义在形参列表的最后,且只能有一个。
package com.qfedu;
public class Test11 {
public static void main(String[] args) {
printArr("长江","黄河","吕布");
//1.定义
String[] arrHeroName = new String[3];
arrHeroName[0] = "貂蝉";
arrHeroName[1] = "如花";
arrHeroName[2] = "如花";
printArr(arrHeroName);
}
//参数类型... 参数名称
//1.传入的值必须都是同类型
//2.语法:数据类型... 形参名 //必须定义在形参列表的最后,且只能有一个。
//3.可以当成数组循环
public static void printArr(String... arr) {
for(int i=0; i<arr.length; i++) {
System.out.println(arr[i]);
}
}
}
九、数组的排序【重点】
9.1 冒泡排序:相邻的两个数值比较大小,互换位置
package com.qfedu;
import java.util.Arrays;
public class Test13Sort1 {
public static void main(String[] args) {
int[] weight = new int[5];
//2.赋值
weight[0] = 170;
weight[1] = 160;
weight[2] = 140;
weight[3] = 130;
weight[4] = 110;
System.out.println("原来的:"+Arrays.toString(weight));
bubbleSort(weight);
int length = weight.length;
//第三种方式:冒泡排序
//第一次: i =0;
for(int j=0; j<length-1; j++) {
if(weight[j] > weight[j+1]) {
int temp =0;
temp = weight[j];
weight[j] = weight[j+1];
weight[j+1] = temp;
}
}
System.out.println("第一次:"+Arrays.toString(weight));
//第二次: i =1;
for(int j=0; j<length-1-1; j++) {
if(weight[j] > weight[j+1]) {
int temp =0;
temp = weight[j];
weight[j] = weight[j+1];
weight[j+1] = temp;
}
}
System.out.println("第二次:"+Arrays.toString(weight));
//第三次: i =2;
for(int j=0; j<length-1-2; j++) {
if(weight[j] > weight[j+1]) {
int temp =0;
temp = weight[j];
weight[j] = weight[j+1];
weight[j+1] = temp;
}
}
System.out.println("第三次:"+Arrays.toString(weight));
//第四次: i =3;
for(int j=0; j<length-1-3; j++) {
if(weight[j] > weight[j+1]) {
int temp =0;
temp = weight[j];
weight[j] = weight[j+1];
weight[j+1] = temp;
}
}
System.out.println("第四次:"+Arrays.toString(weight));
}
public static void bubbleSort(int[] arr) {
System.out.println("********************");
for (int i=0; i<arr.length-1; i++) {
for(int j=0; j<arr.length-1-i;j++) {
if(arr[j] > arr[j+1]) {
int temp =0;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println("冒泡排序后结果为:"+Arrays.toString(arr));
System.out.println("********************");
}
}
9.2选择排序:固定值与其他值依次比较大小,互换位置
package com.qfedu.array1;
import java.util.Arrays;
//固定位置 ,然后,拿这个位置 的数和后边进行比较交换
public class TestSort2 {
public static void main(String[] args) {
int[] arr1 = new int[5];
arr1[0] = 70;
arr1[1] = 30;
arr1[2] = 50;
arr1[3] = 45;
arr1[4] = 10;
for(int i=0;i<=(arr1.length-1-1); i++) {
for(int j=(i+1); j<=(arr1.length-1); j++) {
if (arr1[i] < arr1[j]) {
int temp =0;
temp = arr1[i];
arr1[i] = arr1[j];
arr1[j] = temp;
}
}
}
System.out.println(Arrays.toString(arr1));
}
}
9.3 JDK排序:java.util.Arrays.sort(数组名)
Arrays.sort(weight);
System.out.println("排序的第一种方式:"+Arrays.toString(weight));
十、二维数组
10.1 二维数组的概念
概念: 一维数组中的一维数组;数组中的元素,还是数组。
10.2 二维数组的赋值
使用双下标访问二维数组中的元素:
- 第一个下标代表:行号(高维下标)。
- 第二个下标代表:列号(低维下标)。
10.3 二维数组的内存分配
高维数组中的每一个元素,保存了低维数组的地址。访问array[0]等价于在访问0x0000A111。
10.4 二维数组的访问
public class Test2DArray{
public static void main(String[] args){
int[][] nums = new int[3][5];
nums[0][0] = 10;//第一行,第一列
nums[0][3] = 20;//第一行,第四列
nums[1][0] = 30;//第二行,第一列
nums[1][1] = 40;//第二行,第二列
nums[2][2] = 50;//第三行,第三列
nums[2][4] = 60;//第三行,第五列
for(int i = 0 ; i < nums.length ; i++){ //外层控制行数
for(int j = 0 ; j < nums[i].length ; j++){ // j = 1 内层控制列数
System.out.print( nums[i][j] +"\t");
}
System.out.println();
}
System.out.println( nums.length );//nums变量中,所持有的地址对应的数组长度是多少 = 3
System.out.println( nums[0].length );// nums[0],高位数组中的第一个元素所指向的低维数组的长度
System.out.println( nums[0] ); // 长度5 先创建了长度为5的低维数组,将地址赋值给高维空间
System.out.println( nums[1] );
System.out.println( nums[2] );
}
}
10.5 二维数组创建语法
- 先声明、再分配空间:
- 数据类型[][] 数组名;
- 数组名 = new 数据类型[高维长度][低维长度];
- 声明并分配空间:
- 数据类型[][] 数组名 = new 数据类型[高维长度][低维长度];
- 声明并赋值(繁):
- 数据类型[][] 数组名 = new 数据类型[高维长度][]; (不规则数组,自行new低维数组)。
- 声明并赋值(简):
- 数据类型[][] 数组名 = { {v1,v2,v3},{v4,v5},{v6,v7,v8,v9} }; (显示初始化)。
public class Test2DArray2{
public static void main(String[] args){
int[][] array = new int[3][]; //只有高维空间,没有低维空间
array[0] = new int[5];
array[1] = new int[3];
array[2] = new int[7];
System.out.println(array[0]);
System.out.println(array[1]);
System.out.println(array[2]);
System.out.println(array[0].length);
System.out.println(array[1].length);
System.out.println(array[2].length);
for(int i = 0 ; i < array.length ; i++){
for(int j = 0 ; j < array[i].length ; j++){
System.out.print(array[i][j] +"\t");
}
System.out.println();
}
//显示初始化
int[][] numbers = { {1,2,3} , {4,5,6,7} , {8,9} };
System.out.println(numbers.length);
System.out.println("--------------");
System.out.println(numbers[0].length);
System.out.println(numbers[1].length);
System.out.println(numbers[2].length);
}
}