第六节 数组
数组的概念
一组连续的储存空间,存储多个相同数据类型的值
数组的特点
类型相同
长度固定
数组的组成
数组中每个数据格被称为“数组元素”。
对每个元素进行赋值或取值的操作被称为“元素的访问”。
访问元素时,需要用“下标”(从0开始,依次+1,自动生成)
访问语法:数组名[下标]:例如 存:a[0]=10,取:a[0];
数组的声明与赋值
声明int数组类型的变量,定义变量名为a
int [] a=new int[5];
需要在内存中找到长度为5的连续空间,来存储数组
下标范围
有效下标范围:0~数组长度-1
访问无效下标,会导致数组下标(索引)越界异常,java.lang.ArrayIndexOutOfBoundsException
数组的默认值
在没有为数组元素赋值的情况下,依旧可以正确访问,
数组默认值:整数:0,小数:0.0,字符:空格,布尔:false,其他:null
数组创建语法
先声明、再分配空间
数据类型[]数组名:
数组名=new 数据类型[长度];
声明并分配空间
数据类型[] 数组名=new 数据类型[长度];
声明并赋值(繁)
数据类型[] 数组名=new 数据类型[ ]{元素1,元素2,元素3,……};
声明并赋值(简)
数据类型[] 数组名={元素1,元素2,元素3,……}
//显式初始化,注意,不可换行。
数组的遍历
遍历:从头至尾,逐一对每个元素进行访问`
int[] a=new int [5];
for(int i=0;i<a.length;i++){
System.out.print(a[i]+"\t")
//用循环变量i充当下标,逐一访问每个元素。
}
System.out.println(a.lentgh);
//可获得数组元素长度
数组的扩容
创建数组时,必须指定数组长度,并在创建之后不可更改长度。
扩容思路
创建大于原数组长度的新数组
将原数组中的元素依次复制到新数组中
复制方式
循环将原数组中所有元素逐一赋值给新数组
int []arr=new int[]{11,22,33,44,55};
//1,逐一复制
//创建一个新数组arr1,确定数组长度
int [] arr1=new int[arr.lenght*2]
//用循环的方式将原数组中每一个元素复制给新数组,
for(int i=0;i<arr.length;i++){
arr1[i]=arr[i]
}
//2,用System.arraycopy(原数组,原数组起始,新数组,新数组起始,复制长度)的方式直接复制
//创建一个新数组
int[] arr2=new int[arr.length*2];
System.arraycopy(arr,0,arr2,0,arr.length);
//起始元素可以为任意值,复制长度也可以任意值,但要注意数组索引越界
//3,用数组工具,java.util.Arrays.copyOf(原数组,新数组长度),这个直接能生成一个数组返回。
java.util.Arrays.copyOf(arr,arr.length*2);
//这种的数组长度可以比原数组长或者短
//用forEach方式遍历每个元素,没有被赋值的元素用默认值
for(int i:arr1){
System.out.print(i+"\n");
}
System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度)
java.util.Arrays.copyOf(原数组,新长度);//返回带有原值的新数组。
地址的替换
数组作为引用类型之一,其变量中存储的是数组的地址。
完成元素复制后,需将新数组地址,赋值给原变量进行替换。
arr 0x00001001 11 22 33 44 55
arr 0x00001002 11 22 33 44 55 0 0 0 0 0
栈内存中存储的是对象的地址,堆内存中存储的是数组元素
如果是二维数组,堆内存中存储的是一维数组的地址,地址又指向堆内存中的数组元素
数组类型的参数和返回值
public class TestArray{
public static void main(String[] args){
int[] nums={11,22,33,44};
printArray(nums);
System.out.println("===============================");
printArray(expand(nums));
}
//数组类型的参数
public static void printArray(int[] arr){
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+"\t");
}
System.out.println();
}
//数组类型的返回值
public static int[] expand (int [] arr){
return java.util.Arrays.copyOf(arr,arr.length*2);
}
}
方法调用时:将nums中的地址赋值给arr,此时二者指向同一个数组。
传递参数时:基本数据类型传递的是变量中的值,引用数据类型传递的是变量中的地址。
可变长参数
概念:可接收多个同类型实参,个数不限,使用方式与数组相同。
语法:数据类型…形参名//必须定义在形参列表的最后,且只能有一个
public class TestVarialbeMethod3 {
public static void main(String[] args) {
printHobby("张三");//i have no hobby
printHobby("张三","playchanse");
printHobby("张三","playbasketball","watchtv","music");
//i like playbasketball watchtv music
}
public static void printHobby(String name,String ...hobbys) {
if(hobbys.length==0) {
System.out.println("i have no hobby");
return;
}
String str="i like ";
//这个后面要有个空格 这样才能让后面出来的空开,不至于连在一起
for (String h : hobbys) {
str +=(h+" ");//str=str+h+" "
}
System.out.println(str);
}
}
数组的排序
冒泡排序:相邻两个数值比较大小,互换位置
规律:外层循环length-1,内层循环length-1-i;
int [] arr=new int[]{11,22,33,44,55};
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=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
选择排序:固定值与其他值依次比较大小,互换位置
int [] arr=new int[]{11,22,33,44,55};
for(int i=0;i<arr.length;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[j]<arr[i]){//升序
int temp=arr[j];
arr[j]=arr[i];
arr[i]=temp;
}
}
}
java.util.Arrays.sort(arr);
//自动执行了升序操作。这是一个没有返回值的方法
jkd排序:java.util.Arrays.sort(数组名);jdk提供的(升序)
数组的应用
二维数组
概念:一维数组中的一维数组;数组中的元素还是数组
二维数组相当于一个多行多列的表格
int [][]arr=new int[5][3];
二维数组的赋值
arr[0][0]=10;
arr[4][2]=20;
使用双下标访问二维数组中的元素
第一个下标代表行,高维下标
第二个下标代表列:低维下标
二维数组的内存分配
高维数组中的每一个元素,保存了低维数组的地址,访问arr[0]等价于在访问二维数组内元素一维数组的地址。
二维数组的遍历及访问
int[][]arr=new int[3][];
//不规则二维数组,低维数组长度不写必须要赋值,不然报数组索引越界异常
arr[0]=new int[3];
arr[0][0]=1; arr[0][1]=2; arr[0][2]=3;
arr[1]=new int[2];
arr[1][0]=4; arr[1][1]=5;
arr[2]=new int[4];
arr[2][0]=7; arr[2][1]=8; arr[2][2]=9;arr[2][3]=10;
int[][]arrs=new int[3][];
arrs[0]=new int[] {1,33,54,5,};
arrs[1]=new int[] {1,3,44,5,19,3};
arrs[2]=new int[] {1,23,4,};
arrs[3]=new int[] {1,31,44,95,19,11};
System.out.println("用for循环来遍历数组");
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}
System.out.println("用forEach来遍历数组,");
for(int[] A:arr){
for(int a:A) {
System.out.print(a+"\t");
}
System.out.println();
}
二维数组打印杨辉三角
/*
* 1
* 1 1
* 1 2 1
* 1 3 3 1
* 1 4 6 4 1
* 1 5 10 10 5 1
*/
package array4_4;
import java.util.Scanner;
public class TestYHSJ {
static Scanner input=new Scanner(System.in);
public static void main(String[] args) {
System.out.println("请输入一个行数");
int row=input.nextInt();
// print(jisuan(fuzhi(ewsz(row))));
printYHSJ(jisuan(fuzhi(ewsz(row))));
}
//创建不同长度的二维数组。
public static int[][] ewsz(int row) {
int [][]ewsz=new int[row][];
for(int i=0;i<row;i++) {
ewsz[i]=new int[i+1];
}
return ewsz;
}
//二维数组的赋值
public static int[][] fuzhi(int[][] ewsz) {
for(int i=0;i<ewsz.length;i++) {
ewsz[i][0]=1;
ewsz[i][i]=1;
}
return ewsz;
}
//二维数组的中间赋值
public static int[][] jisuan(int[][] ewsz) {
for(int i=2;i<ewsz.length;i++) {
for(int j=1;j<i/*ewsz[i].length-1*/;j++) {
ewsz[i][j]=ewsz[i-1][j-1]+ewsz[i-1][j];
}
}
return ewsz;
}
//杨辉三角的打印
public static void printYHSJ(int[][] arr) {
for(int i=0;i<arr.length;i++) {
for(int j=arr.length-1;j>i;j--) {
System.out.print("\t");
}
for(int j=0;j<arr[i].length;j++) {
System.out.print("\t"+arr[i][j]+"\t");
}
System.out.println();
}
}
//打印二维数组
public static void print(int[][]arr) {
for(int i=0;i<arr.length;i++) {
for(int j=0;j<arr[i].length;j++) {
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}
}
}
数组工具
import java.util.Arrays;
public class ArrayTool2 {
public static void main(String[] args) {
double[] arr3 = { 1, 2, 3, 4 };
double[] arr4 = { 1, 2, 3, 4 };
boolean isEquals2 = Arrays.equals(arr3, arr4);
System.out.println(isEquals2);//true
System.out.println(arr3==arr4);//false
//==比较的是地址,equals比较的是数组的内容
Arrays.fill(arr4 ,2.0);
//把数组arr4中所有元素填充为2.0
print(arr4);//2.0 2.0 2.0 2.0
Arrays.fill(arr3,1,4,10 );
//把数组中指定索引的元素修改为10
print(arr3);//1.0 10.0 10.0 10.0
double[][] arr1 = { { 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11, 12 }, { 13, 14, 15, 16, 17 }, };
double[][] arr2 = { { 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11, 12 }, { 13, 14, 15, 16, 17 }, };
boolean isEquals3 = Arrays.equals(arr1, arr2);
System.out.println(isEquals3);//false
System.out.println(arr1==arr2);//false
boolean isEquals = Arrays.equals(arr1[0], arr2[0]);
System.out.println(isEquals);//true
System.out.println(arr1[0]==arr2[0]);//false
}
private static void print(double[] arr4) {
for(double a:arr4) {
System.out.print(a+"\t");
}
System.out.println();
}
public static void print(int[][] arr) {
for (int[] array1 : arr) {
for (int array2 : array1) {
System.out.print(array2 + "\t");
}
System.out.println("内层循环结束");
}
System.out.println("外层循环结束");
}
}
数组随机数练习
/*
* 打印75-100之间的所有数,包含在数组中
*/
import java.util.Arrays;
import java.util.Random;
public class SuiJIShu {
public static void main(String[] args) {
Random r=new Random();
int[]arr=new int[10];
for(int i=0;i<10;i++) {
if(i<arr.length/2){
arr[i]=(r.nextInt(26)+75);
//括号里面写了26,就是0到26之间的整数,都是包左不包右
}else {
arr[i]=(int)(Math.random()*26+75);
//Math.random()括号里面不能写东西,只能乘*26.
}
System.out.println(arr[i]);
}
for(int i:arr) {
System.out.print(i+"\t");
}
System.out.println("\n===============");
System.out.println(arr.toString());
System.out.println(Arrays.toString(arr));
}
}
数组算全班同学成绩
import java.util.Scanner;
public class OneStudent {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("请输入班级学生个数");
int nums=input.nextInt();
double sum=0.0;
double[] arr=new double[nums];
for(int i=0;i<arr.length;i++) {
System.out.println("请输入班级学生成绩");
arr[i]=input.nextDouble();
sum+=arr[i];
}
System.out.println("全班同学总成绩为:"+sum);
System.out.println("全班同学平均成绩为:"+sum/nums);
}
}
数组打印俄罗斯方块
package Arrays;
import java.util.Random;
public class GameArraysLS2 {
public static void main(String[] args) {
// printShape(null);
printShape2(getRandomShape());
}
public static void printShape(int[][] shapes) {
for(int i=0;i<4;i++) {
for (int j = 0; j < 4; j++) {
System.out.print("□ ");
}
System.out.println();
}
}
/*
* 打印随机生成的表示二维数组的形状
* shapes 表示俄罗斯方块形状的二维数组
* 看他的坐标在不在4*4的框里面。
*/
public static void printShape2(int[][] shapes) {
//在44*4的区域来绘制俄罗斯方块,为什么是4*4,因为里面有7中情况,任何一个俄罗斯方块可以在这个范围内显示
for(int i=0;i<4;i++) {
for (int j = 0; j < 4; j++) {
boolean flag=false;
for (int k = 0; k < 4; k++) {
if(shapes[k][0]==i&&shapes[k][1]==j) {
flag=true;
break;
}
}
//判断给定的点的坐标x=i,y=j每个形状4个点。一个表示俄罗斯方块的二维数组。
if(!flag) {//这里的flag是判断的,flag为true的时候打印实心,flag为false
System.out.print("□ ");
}else {
System.out.print("■ ");
}
}
System.out.print("\n");
}
System.out.println();
}
/*
* 借助随机数来生成一个表示俄罗斯方块的二维数组
*/
public static int[][] getRandomShape() {
//得到一个随机的表示俄罗斯方块的二维数组。
Random r = new Random();
int shape = r.nextInt(7);
int type = r.nextInt(4);
int[][] shapes = new int[4][2];
switch (shape) {
case 0: // 方块
shapes = new int[][]{{0, 0}, {0, 1}, {1, 0}, {1, 1}};
break;
case 1: // 长条
switch (type) {
case 0:
case 2: // 横条
shapes = new int[][]{{0, 0}, {0, 1}, {0, 2}, {0, 3}};
break;
default: // 数条
shapes = new int[][]{{0, 0}, {1, 0}, {2, 0}, {3, 0}};
break;
}
break;
case 2: // T
switch (type) {
case 0: // T
shapes = new int[][]{{0, 0}, {0, 1}, {0, 2}, {1, 1}};
break;
case 1: // -|
shapes = new int[][]{{0, 1}, {1, 0}, {1, 1}, {2, 1}};
break;
case 2: // 土
shapes = new int[][]{{0, 1}, {1, 0}, {1, 1}, {1, 2}};
break;
default:// |-
shapes = new int[][]{{0, 0}, {1, 0}, {2, 0}, {1, 1}};
break;
}
break;
case 3://L形状
switch(type) {
case 0:
shapes=new int[][] {{0,0},{1,0},{2,0},{2,1}};
break;
case 1:
shapes=new int[][] {{0,0},{1,0},{0,1},{0,2}};
break;
case 2:
shapes=new int[][] {{0,0},{0,1},{1,1},{2,1}};
break;
default :
shapes=new int[][] {{0,2},{1,0},{1,1},{1,2}};
break;
}
break;
case 4://反L
switch(type) {
case 0:
shapes=new int[][] {{0,0},{1,0},{2,0},{2,1}};
break;
case 1:
shapes=new int[][] {{0,0},{0,1},{0,2},{1,2}};
break;
case 2:
shapes=new int[][] {{0,1},{1,2},{2,0},{2,1}};
break;
default:
shapes=new int[][] {{0,0},{1,0},{2,0},{2,1}};
break;
}break;
case 5://Z
switch(type) {
case 0:
case 2:
shapes=new int[][] {{0,0},{0,1},{1,1},{1,2}};
break;
default:
shapes=new int[][] {{0,1},{1,0},{1,1},{2,0}};
break;
}break;
case 6://反Z
switch(type) {
case 0:
case 2:
shapes=new int[][] {{1,0},{1,1},{0,1},{0,2}};
break;
default :
shapes=new int[][] {{0,0},{1,0},{1,1},{2,1}};
break;
}
break;
}
return shapes;
}
}