1 数组
1.1 数据结构
数据结构是计算机存储、组织数据的方式。
数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。
通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。
数据结构往往同高效的检索算法和索引技术有关。
1.2 数组
引用数据类型,用来保存多个数据
1.3数组特性:
内存中连续存储,并且下表从0开始(内存地址偏移)
数组长度一旦确定,长度不能更改,故数组不能进行添加删除操作
除非新建数组,把原数组数据复制到新数组中,在复制的过程中可以进行添加和删除操作
所以 数组的查询和更改 效率是很高的,但是 添加和删除效率
数组都有一个内置属性 length 保存了数组的长度
在Java中 有一个 Java.util.Array类 提供了一些数组操作
1.4数组声明:
1.4.1 静态声明:
在已知每个元素的时候,使用静态声明
数据类型 变量名 = 值;
int i = 2 ;
数据类型[] 变量名 = {值,值,.....}; 简写方式
数据类型[] 变量名 = new 数据类型[]{值,值,.....}; 方式
int[] arr = {1,2,3,4,5,6};//类型加中括号
int[][] arr = {
{1,2},{1,2},{1,2}
};
1.4.2 动态声明:
不知道数组中每个元素的时候,使用动态声明
数据类型[] 变量名 = new 数据类型[长度];
int[] arr = new int[长度];
package _01_Array;
/**
* @author 16200
*2022年1月4日上午10:28:46
*/
public class Array_01 {
public static void main(String[] args) {
//静态声明
int[] arr = {1,2,3,4};
}
}
2 数组使用
package _01_Array;
/**
* 数组使用
*
* 获取数组
*
* @author 16200
*2022年1月4日上午11:34:02
*/
public class Array_02 {
public static void main(String[] args) {
//静态初始化一个数组
int[] arr = {1,2,3};
//获取 : 数组[下标] 注意下标从0开始
System.out.println(arr[0]);
//数组长度:数组.length
System.out.println(arr.length);
//最后一个元素
System.out.println(arr[arr.length-1]);
//更改
//数组[下标] = 值;
arr[0] = 2;
//遍历
// System.out.println(arr[0]);
// System.out.println(arr[1]);
// System.out.println(arr[2]);
for (int i = 0 ; i< arr.length;i++){
System.out.println(arr[i]);
}
//增强for循环 foreach
//把数组中的每一个元素,都赋值给变量
//for(数据类型 变量名 : 数组){}
for (int element : arr){
System.out.println(element);
}
}
}
3 常见异常
package _01_Array;
/**
* 常见异常
1 下标越界
2 空指针异常
*
* @author 16200
*2022年1月4日上午11:44:32
*/
public class Array_03 {
public static void main(String[] args) {
int[] arr = {1,2,3,4};
//System.out.println(arr[4]);下标越界
//加入没有对数组进行初始化操作,默认是null
arr = null;
// System.out.println(arr.length);空指针异常
//如果数据没有进行初始化,但是对数组进行了属性操作,会导致 空指针异常
// System.out.println(arr[0]);
}
}
4 传参
package _01_Array;
public class Array_04 {
public static void main(String[] args) {
int i = 2;
m1(i);
int arr[] = {1,2};
m2(arr);//字面值传参
}
public static void m1 (int i){
}
public static void m2(int[] arr){
}
}
package _01_Array;
/**
* 传值 指传递基本类型的数据
*
* 传址/传引用 指的是传递引用数据类型的值
*
* 基本类型传递后, 相互没有影响,因为指向不同的空间
*
* 传引用指向的是同一个堆内存对象空间,相互有影响
* 故数组更改不需要返回值
*
* @author 16200
*2022年1月4日下午2:13:07
*/
public class Array_06 {
public static void main(String[] args) {
int i = 10;
m1(i);
System.out.println("main="+i);
int[] arr= {1,2};
m2(arr);
System.out.println("main=");
for (int i1 = 0 ; i1 < arr.length; i1++){
System.out.println(arr[i1]+" ");
}
}
public static void m1 (int i){
i = 20 ;
System.out.println("m1="+i);//基本数据类型传值,在方法中另行储存,对值得修改不影响原来的变量
}
public static void m2(int[] arr){//引用类型传递的是地址,方法中的更改会影响存储的值
arr[0] = 11;
System.out.println("m2=");
for (int i = 0 ; i < arr.length; i++){
System.out.println(arr[i]+" ");
}
}
}
5 数组复制
package _01_Array;
/**
* 数组复制
*
*
* @author 16200
*2022年1月4日下午2:31:12
*/
public class Array_07 {
public static void main(String[] args) {
//原数组
int[] src = {2,3,4,5,6,7,8};
//目标数组
int[] dest = {11,12,13,14,15,16,17,18};
// copy(src,dest,2,3,3);
// 源数组,源数组起始位置(包含当前位置),目标数组,目标数组起始位置,复制个数
// 因为是替换式复制,只是把原来的数据更改了,并没有重新生成数组,所以不需要返回值,因为是传引用
System.arraycopy(src,2,dest,3,3);//有现成的方法可调用
for (int i = 0;i < dest.length;i++){
System.out.println(dest[i]);
}//数组不用返回值
}
public static void copy(int[] src,int[] dest ,int srcPos, int destPos, int length){
// //原数组
// int[] src = {2,3,4,5,6,7,8};
// //目标数组
// int[] dest = {11,12,13,14,15,16,17,18};
//更改为{11,12,13,4,5,6,17,18}
for (int i = srcPos ,j = destPos; i <srcPos+length;i++,j++){//i = 原数组起始位置,j = 目标数组起始位置; i < 源起始位置+复制个数;
dest[j] = src[i];
}
}
}
5.1 数组插入复制
package _01_Array;
/**
* 数组插入复制
*
* @author 16200
*2022年1月4日下午3:20:17
*/
public class Array_08 {
public static void main(String[] args) {
//原数组
int[] src = {2,3,4,5,6,7,8};
//目标数组
int[] dest = {11,12,13,14,15,16,17,18};
// int[] dest = {11,12,13,14,4,5,6,15,16,17,18};
int[] result = copy(src,2,dest,3,3);
for (int i = 0;i < result.length;i++){
System.out.println(result[i]);
}
}
/**
*插入复制
*
* @param src
* 源数组
* @param srcPos
* 源数组起始位置
* @param dest
* 目标数组
* @param destPos
* 目标数组起始位置
* @param length
* 插入个数
* @return
*/
public static int[] copy (int[] src, int srcPos,int[] dest, int destPos, int length){
//因为是插入复制,所以肯定会更改数组长度,因为数组长度不能更改,所以我们只能新建数组,并通过返回值把数组返回
int[] newDest = new int[dest.length+length];
//1、目标数组中,从0开始,起始位置结束(包含),复制到新数组中
for (int i = 0; i <= destPos; i++){
newDest[i] = dest[i];
}
//2. 源数组中 从起始位置开始(包含) 复制 length到新数组中
//现在需要用到目标数组起始位置并需要更改,后面还要用到目标数组起始位置,所以不可更改
//故新建一个变量index,存储目标数组起始位置,用于更改
int index = destPos;
for (int i = srcPos; i< length+srcPos ;i++){
index++;
newDest[index] = src[i];
}
//3. 目标数组中 从起始位置开始(包含) 到最后 所有的数据 复制到新数组中
for (int i = destPos+1; i < dest.length;i++){
index++;
newDest[index] = dest[i];
}
return newDest;
}
}
6 二维数组
package _01_Array;
//一维数组存储在堆内存,连续存储
//二维数组存储一个数组的地址,该数组存储二维数组中每个一维数组的地址
/**
* 二维数组操作
*
* 声明:
* 静态声明
* int[][] arr = {
* {},
* {},.....
* };
动态声明
int[][] arr = new int[3][4];表示该二维数组中,有3个一维数组,并且每个一维数组中都有4个数据
int[][] arr = new int[3][];表示该二维数组中,有3个一维数组,并且每个一维数组都是null
这种需要单独初始化每一个一维数组的长度,一般用于 每行列不一样的情况(每一个一维数组中,元素个数不同的情况)
arr[0] = new int[5];
arr[1] = new int[3];
arr[2] = new int[15];
*
*
* @author 16200
*2022年1月4日下午3:46:30
*/
public class Array_09 {
public static void main(String[] args) {
//静态
int[][] arr0 ={ {1,2,3},{0,1,2},{1,6,3} };
// //动态
// int[][] arr1 = new int[3][4];
// int[][] arr2 = new int[3][];
// arr2[0] = new int[5];
// arr2[1] = new int[3];
// arr2[2] = new int[15];
//获取数据 数组[下标][下标]
int[] arr3 = arr0[0];
int arr33 = arr3[0];
System.out.println(arr33);
System.out.println(arr0[0][0]);
//获取二维数组中最后一个数据
int[] arr4 = arr0[arr0.length-1];
//arr0.length 为二维数组中有多少个一维数组
int arr44 = arr4[arr4.length-1];
System.out.println(arr0.length);
System.out.println(arr44);
//全部替换之后,得如下
System.out.println(arr0[arr0.length-1][arr0[arr0.length-1].length-1]);
//更改 数组[下标][下标] = 值;
arr0[2][1] = 33;
//遍历
for(int i = 0;i < arr0.length;i++){
for (int j = 0; j<arr0[i].length;j++){//取每个一维数组的长度
System.out.print(arr0[i][j]+" ");
}
System.out.println();
}
}
}
7 动态声明,遍历
package _01_Array;
/**
* 动态声明 遍历
*
* @author 16200
*2022年1月4日下午6:33:25
*/
public class Array_10 {
public static void main(String[] args) {
//二维表
int[][] arr = new int[5][6];
for(int i = 0;i < arr.length;i++){
for (int j = 0; j<arr[i].length;j++){
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
//锯齿状
int[][] arr1 = new int[5][];
//初始化二维数组中的每一个数组
for (int i =0;i < arr1.length;i++){
arr1[i] = new int[i+1];
}
//遍历
for(int i = 0; i < arr1.length;i++){
for (int j = 0 ;j < arr1[i].length;j++ ){
System.out.print(arr1[i][j]+" ");
}
System.out.println();
}
}
}
8 变量值交换
package _01_Array;
/**
* 变量值交换
*
* @author 16200
*2022年1月4日下午4:47:59
*/
public class Array_11 {
public static void main(String[] args) {
int x = 10;
int y = 11;
// 1 中间变量
int temp = x;
x = y;
y = temp;
// 2 位移运算(面试用)
x = 2;
y = 3;
//
x = x ^ y;
y = x ^ y;
x = x ^ y;
// 3 加减运算
x = 10 ;
y = 20 ;
x = x + y;
y = x - y;
x = x - y;
}
}