一.数组
1 一维数组
1.1 数据结构
是计算机存储和组织数据的一种方式,合理选择数据结构能有效提升程序的运行效率和存储效率
数组,列表,红黑数...
1.2 数组的概述及特性
java中数组是引用类型,就意味着保存在堆内存,用于保存多个数据.
数组可以看做是保存了多个相同类型的数据的一个容器,可以对这些数据进行统一管理.
数组在内存空间中是连续存储 (优点查询效率高) 的 ,并且数组一旦确定长度不能修改(横向拓展度差)
数组有一个length属性,保存长度,并且数组通过下标的方式进行访问 (偏移),下标0开始 (内存不偏移)
结合数组保存数据的特征,发现数组在查询修改上效率极高,但是添加和删除效率较低 (数组不能进行添加和删除操作)
1.3 数组声明
静态声明: 在已知数组中每个元素的时候,使用静态声明
数据类型[] 变量名 = new 数据类型[] {值,值,值,...}
(简写方式) 数据类型[] 变量名={值,值,..};仅限于创建数组时使用,后续赋值,不能这样写
动态声明: 不知道数组中每个元素的时候,使用动态声明 需要指定长度,
数组中保存的为对应类型的默认值
整数0,小数0.0,字符型\u0000,布尔型false,引用类型null
数据类型[] 变量名= new 数据类型[长度];
//静态声明
int[] arr1 = new int[] {1,2,3};
int[] arr2 = {1,2,3};
//动态声明
int[] arr3 = new int[10];
1.4 数据存储
引用类型保存的是地址,数据存储在堆内存中
1.5 数组的使用
1.5.1 查询-获取数据
查询: 数组[下标] 下标从0开始
int[] arr = {1,2,3,4,5};
System.out.println(arr[3]);
//最后一个数据
System.out.println(arr[arr.length-1]);
System.out.println(arr[3]);
1.5.2 修改-设置数据
修改: 数组[下标]=值;
arr[2]= 44;
1.5.3 遍历
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
}
1.6 数组常见异常
1.下标越界 java.lang.ArraylndexOutOfBoundsException: 3
当下标小于0 或 大于等于length的时候,就会出现这个异常
int[] arr = {1,2,3}; System.out.println(arr[3]);
2.空指针异常 java.lang.NullPointerException
当一个对象是null的时候,我们进行了成员属性访问,就会出现空指针异常(一般是在查询不知道的数组时产生)
int[] arr = {1,2,3}; arr = null; System.out.println(arr[0]);
1.7 数组传递
public static void main(String[] args){
int i = 2;
//传入变量
m1(i);
//传入字面量
m2(2);
int[] arr = {2,3};
//变量
m2(arr);
//m2({2,3})这样的写法是错误的
//数组字面量
m2(new int[] {2,3});
}
public static void m1(int i){
}
public static void m2(int[] arr){
}
1.8 传值和传址
传值: 指的是基本数据类型
public static void m1(int i){
i++;
System.out.println("m1:" + i);
}
public static void main(String[] args){
int i = 10;
m1(i);
System.out.println("main:" + i);
}
m1方法中i为局部变量(局部变量的值存储在方法自己的栈内存中)加一后并不会影响main中i的值(main中i的值存储在main方法的栈内存中);
传址: 指的是引用数据类型
public static void m2(int[] arr){
arr[0] = 11;
System.out.println("m2Arr:" + arr[0]);
}
public static void main(String[] args){
int[] arr = {1,2,3};
m2(arr);
System.out.println("mainArr:" + arr[0]);
}
数组类型保存的是地址,因此在m2调用是会直接将其引导到堆地址中,进行修改将直接修改数组中的数据,在之后的main方法输出时数组的值已经改变,因此结果都为11.
1.9 数组复制
public static void main (String[] args){
int[] src = { 1,2,3,4,5,6 };
int[] dest = { 11,12,13,14,15,16 };
//把src中的4,5,6放到14,15,16这里
m1(src,3, dest, 3,3);
for (int i = O; i < dest.length; i++){
System.out.printIn(dest[ih;
}
}
public static void m1(int[]src, int srcIndex, int[]dest, int destindex,int length) {
for (int i = o; i< length; i++){
dest[destlndex] = src[srclndex];
destIndex++;
srcIndex++;
}
}
2.二维数组
2.1 数组声明
//数据类型变量名={值};
//[数据类型]变量名={值,值...};
int i = 2;
int age = 2;
int[] arr = {2,3,4};
int[][] arr2 = {{1,2,3},{2,3,4},{5,4},{11,14,16}};
//动态声明
//有5个一维数组,每个一维数组中有6个数据
int[][]arr3 = new int[5][6];
可以动态设置每一个数组的长度
2.2 数组存储
二维数组中保存一维数组的地址,一维数组保存数据
int[][] arr = { {1,2,3}, {4,5,6}, {11,12,13} }
2.3 数组使用
int[][] arr2 = {{1,2,3},{2,3,4},{5,4},{11,14,16}};
//获取第一个一维数组中的第一个数据
int[] arr2_0 = arr2[0];
int arr2_0_0 = arr2_0[0];
System.out.println(arr2_0_0);
System.out.println(arr2[0][0]);
//获取最后一个一维数组中的最后一个数据
int[] arr2_3 = arr2[arr2.length - 1];
int arr2_3_2 = arr2_3[arr2_3.length - 1];
System.out.printIn(arr2_3_2);
system.out.println(arr2[arr2.length - 1][arr2[arr2.length - 1].length - 1]);
arr2_3_2 = arr2_3[arr2_3.length - 1] = arr2[arr2.length - 1][arr2[arr2.length - 1].length - 1]
//修改
//把第二个一维数组中的第二个数据改成33
int[] arr2_1 = arr2[1];
arr2_1[1] = 33;
arr2[1][1] = 33;
2.4 接受用户输入
import java.util.Scanner;
public class Scanner{
public static void main(String[] args){
//接收用户输入
Scanner scanner = new Scanner(System.in);
//程序执行到这里,就会进入等待,等待用户输入之后,再继续执行
//next:接收用户输入的数据,按回车终止
//并且空格是分隔符,一个next只能获取一个
String input = scanner.next();
System.out.println(input);
//接收一行,不需要分隔符,按回车终止
String input = scanner.nextLine();
System.out.println(input);
//接收int类型的值,不能有汉字及特殊符号,必须是纯数字,小数点也不能有,
//否则会报错 java.util.lnputMismatchException
//空格是分隔符
int input = scanner.nextlnt();
System.out.println(input);
//具体用法同nextlnt,只是可以识别一个小数点
double input = scanner.nextDouble();
System.outprintIn(input);
}
}