Bootstrap

07 Java数组与数组操作(定义+遍历+排序+增删改查)

07 数组

7.1 概念

数组在内存中是一块连续的空间,可以保存相同类型多个数据的容器

7.1.1 数组的特点
  • 数组中保存数据必须是相同的数据类型
  • 数组是定长的(数组一旦定义不能改变长度)
7.2 数组的创建
public class Demo {
    public static void main(String[] args) {
        //1 数组的声明
        //方式1,推荐
        //int age;
        int[] nums1;
        double[] scores;
        String[] names;
        //方式2
        int nums2[];
        //2 数组的初始化
        //2.1 静态初始化
        //初始化时由程序员指定每个数组元素的初始值,由系统计算数组长度。
        nums1=new int[]{10,15,12,5,8};
        scores=new double[]{99.5,80.5,92.5};
        names=new String[]{"面向对象","数组","方法","大恐龙","小洋葱"};
        int[] nums3=new int[]{100,200,300,400,500};
        //静态初始化简写方式,必须是一条语句完成
        int[] nums4={22,18,19,25,32};
 
        //2.2 动态初始化
        //初始化时只指定数组长度【大于等于0整数】,由系统为数组元素分配默认值。
        int[] nums5=new int[5]; // byte short int long  默认值0
        double[] score2=new double[100];  // float double 默认值 0.0
        char[] cs=new char[5]; //char 默认值 '\u0000'
        boolean[] bs=new boolean[5]; //boolean 默认值 false
        String[] cities=new String[10]; // String 引用类型的默认值都是null
 
        //注意:静态初始化和动态初始化不能同时使用
        int[] arr=new int[]{20,22,18,15,32};
 
    }
}
7.2.1 动态初始化
  • 语法1: 数据类型[] 数组名 = new 数据类型[长度];
  • 语法2: 数据类型 数组名[] = new 数据类型[长度];
int[] arr = new int[3];

//存数据
arr[0] = 11;
arr[1] = 22;
arr[2] = 33;

//取数据
System.out.println("第二个元素为:"+arr[1]);
System.out.println("第三个元素为:"+arr[2]);

//获取数据的长度
System.out.println(arr.length);

//错误:数组下标越界
System.out.println(arr[3]);
7.2.2 静态初始化
  • 语法1:数据类型[] 数组名 = {数据1,数据2,…};
  • 语法2:数据类型 数组名[] = {数据1,数据2,…};
  • 语法3:数据类型[] 数组名 = new 数据类型[]{数据1,数据2,…};
String[] names = new String[]{"张三","李四","王五","赵六"};
// [Ljava.lang.String;@15db9742      如果直接打印数组,输出的是内存地址
// System.out.println(names);

//操作数组

//存数据
names[0] = "cxk";
names[1] = "尼古拉斯";

//取数据
System.out.println("第二个元素"+names[1]);
System.out.println("第四个元素"+names[3]);

//获取数组的长度
System.out.println("数组的长度:"+names.length);
7.2.3 数组的细节
  1. 数组中的每一个数据称之为数组元素
  2. 数组中的每一个元素都对应有一个下标
  3. 数组中的下标范围0~数组的长度-1
  4. 数组的长度通过数组名.length获取
  5. 数组的长度如果超出的边界会报错(ArrayIndexOutOfBoundsException数组下标越界异常)
7.3 数组的遍历

遍历:获取、保存数据中每一个元素(循环)

//定义一个数组
int[] arr1 = {10,9,17,18,22,34};

//遍历输出数组中的元素
for(int i = 0; i < arr1.length; i++) {
    //arr1[i]表示数组中的每一个元素
    System.out.println(arr1[i]);
}
System.out.println("=============给数组的元素赋值====================");
Scanner sc = new Scanner(System.in);

int[] arr2 = new int[4];
//遍历数组给数组中的元素赋值
for (int i = 0; i < arr2.length; i++) {
    System.out.println("请输入第"+(i+1)+"个元素");
    arr2[i] = sc.nextInt();
}

for (int i = 0; i < arr2.length; i++) {
    System.out.println(arr2[i]);
}

完整示例:

public class Demo {
    public static void main(String[] args) {
        //数组的遍历
        int[] nums=new int[]{20,18,22,15,28};
        double[] scores=new double[]{99,98,100,95,90};
        //使用for循环
        for (int i = 0; i < nums.length; i++) {
            System.out.println(i+"\t"+nums[i]);
        }
        System.out.println("----------------");
        for (int i = 0; i < scores.length; i++) {
            System.out.println(i+"\t"+scores[i]);
        }
        System.out.println("JDK1.5可以使用增强for遍历数组");
        for(int n : nums){ // n 数组中每个元素
            System.out.println(n);
        }
        System.out.println("-------------");
        for(double n : scores){
            System.out.println(n);
        }
        //增强for模板 数组.iter
        for (int num : nums) {
 
        }
        for (double score : scores) {
 
        }
    }
}

增强for模板 数组.iter

​ 练习

import java.util.Scanner;
 
/**
 * @author wgy
 * @version 1.0
 * @date 2023/1/6 14:23
 * @poject day09
 */
public class Demo {
    public static void main(String[] args) {
        //printAvg();
        //show();
        printCity();
    }
    //1 给定一个整型数组,统计数组中所有元素的平均值。
    public static void printAvg(){
        int[] nums=new int[]{90,95,92,100,93,80,85,86,78,75};
        //遍历数组   数组名.fori   数组名.iter
        int sum=0;
//        for (int i = 0; i < nums.length; i++) {
//            sum+=nums[i];//求和
//        }
        for (int n : nums) {
            sum+=n;
        }
        double avg=(double)sum/nums.length;
//        System.out.println("平均数:"+avg);
        System.out.printf("%.2f",avg);
    }
 
    //2 给定一个整型数组,输入一个整数n,如果n在数组中存在,输出下标,不存在则输出-1。
    public static void show(){
        int[] nums={10,8,5,6,12,15,5,20,5,22};
        Scanner input=new Scanner(System.in);
        System.out.println("请输入一个数字");
        int n=input.nextInt();
        //遍历
        boolean flag=false;
        for (int i = 0; i < nums.length; i++) {
            if(n==nums[i]){
                flag=true;
                System.out.println("下标是:"+i);
            }
        }
        if(!flag){
            System.out.println(-1);
        }
    }
 
    //3 控制台输入5个城市的名称,使用数组保存,并遍历输出。
    public static void printCity(){
        //创建数组
        String[] cities=new String[5];
        Scanner input=new Scanner(System.in);
        //给数组的元素赋值
        for (int i = 0; i < cities.length; i++) {
            System.out.println("请输入第"+(i+1)+"个城市");
            String c=input.next();
            //把c 放入数组中
            cities[i]=c;
        }
        System.out.println("---------遍历------------");
        for (String city : cities) {
            System.out.println(city);
        }
    }
}
7.4 数组的默认值
  • 整数型数组默认值:0
  • 浮点型数组默认值:0.0
  • 布尔类型数组默认值:false
    字符型数组默认值:0 或者’ '或者 ‘\u0000’
  • 引用类型数组默认值:null

null是一种特殊的值,表示当前对象在内存中没有指向任何地址。

""表示空字符串,在内存中有对应的内存地址

7.5 数组的应用

​ 案例:

  1. 从键盘录入五个名字到数组中,遍历数组输出这五个名字

  2. 给定一个数组,求数组的最大值

  3. 给定一个数组,求数组的最小值

  4. 给定一个数组,求数组的平均值

  5. 给定一个数组,传入一个数字,如果在数组中存在这个数字,输出这个数字在数组中的下标,否则输出-1

public class Demo {	
	public static void main(String[] args) {
		String[] names = makeNames();
		for (int i = 0; i < names.length; i++) {
			System.out.println(names[i]);
		}
	}	
	//1、从键盘录入五个名字到数组中,遍历数组输出这五个名字
	public static String[] makeNames() {
		Scanner sc = new Scanner(System.in);
		String[] names = new String[5];
		for (int i = 0; i < names.length; i++) {
			System.out.println("请输入第"+(i+1)+"个人的名字");
			names[i] = sc.next();
		}
		return names;
	}
}

public class Demo {
	public static void main(String[] args) {
		int[] arr = {2,3,4,5,6,6,22,33};
		System.out.println(max(arr));
		System.out.println(min(arr));
		System.out.println(avg(arr));
	}
	//2、给定一个数组,求数组的最大值
	public static int max(int[] arr) {
		//假设一个最大值
		int max = arr[0];
		//遍历数组
		for (int i = 0; i < arr.length; i++) {
			if(max < arr[i]) {
				max = arr[i];
			}
		}
		return max;
	}
	//3、给定一个数组,求数组的最小值
	public static int min(int[] arr) {
		//假设一个最小值
		int min = arr[0];
		//遍历数组
		for (int i = 0; i < arr.length; i++) {
			if(min > arr[i]) {
				min = arr[i];
			}
		}
		return min;
	}
	//4、给定一个数组,求数组的平均值
	public static double avg(int[] arr) {
		double sum = 0;
		for (int i = 0; i < arr.length; i++) {
			sum = sum + arr[i];
		}
		return sum/arr.length;
	}	
}
public class Demo {
	public static void main(String[] args) {
		int[] arr = {2,3,4,5,6,6,22,33};
		System.out.println(getIndex(arr, 6));
	}
	//5、给定一个数组,传入一个数字,如果在数组中存在这个数字,输出这个数字在数组中的下标,否则输出-1
	public static int getIndex(int[] arr,int num) {
		for (int i = 0; i < arr.length; i++) {
			if(num == arr[i]) {
				return i;
			}
		}
		return -1;
	}
}
7.6 数组的扩容
7.6.1 数组扩容和缩容

数组的扩容和缩容

  • 步骤1:定义一个新数组,然后新数组的长度比原数组增加或者是减小
  • 步骤2:将原来数组的元素拷贝到新数组中
  • 步骤3:将原数组的变量指向新数组

​ 数组扩容示例

//定义原数组
int[] arr1 = {1,3,46,22,11};

//1、定义新数组   扩容
int[] arr2 = new int[arr1.length+1];

//将原来数组的元素拷贝到新数组中
//arr2[i] = arr1[i]

//2、数组的拷贝
for (int i = 0; i < arr1.length; i++) {
    arr2[i] = arr1[i];
}

//3、将原数组的变量指向新数组
arr1 = arr2;

for (int i = 0; i < arr1.length; i++) {
    System.out.println(arr1[i]);
}

​ 数组缩容

//定义原数组
int[] arr1 = {1,3,46,22,11};

//1、定义新数组
int[] arr2 = new int[arr1.length-1];

//2、数组拷贝
for (int i = 0; i < arr2.length; i++) {
    arr2[i] = arr1[i];
}

//3、将原数组的变量指向新数组
arr1 = arr2;

for (int i = 0; i < arr2.length; i++) {
    System.out.println(arr1[i]);
}
7.6.2 数组拷贝

数组的拷贝有三种方式:

  • 通过自定义循环将原数组中的元素拷贝到新数组中
  • System类提供数组拷贝方法
  • Arrays类提供数组拷贝方法
//1、System类提供数组拷贝方法
int[] arr1 = {1,3,46,22,11};

//定义目标数组
int[] arr2 = new int[arr1.length + 5];

/**
* src:原数组
* srcPos:原数组的起始位置
* dest:目标数组
* destPos:目标数组的起始位置
* length:拷贝的长度
*/
System.arraycopy(arr1, 1, arr2, 3, 4);

for (int i = 0; i < arr2.length; i++) {
    System.out.print(arr2[i]+"\t");
}

​ 使用Arrays工具类

//2、Arrays类提供数组拷贝方法
int[] arr1 = {1,3,46,22,11};

/**
 * original:原数组
 * newLength:新数组的长度
 * 返回值:返回新数组 
 */

arr1 = Arrays.copyOf(arr1, arr1.length+1);
for (int i = 0; i < arr1.length; i++) {
    System.out.print(arr1[i]+"\t");
}
7.7 数组排序
7.7.1 冒泡排序

冒泡排序升序思想:

  • 1、将相邻的两个元素进行比较,如果前面一个元素比后面的大,就交换位置(一轮比较)
  • 2、将上面的操作循环(比较n-1轮)
冒泡排序原理分析
//冒泡排序关系
public class newArray {
    public static void main(String[] args) {
        int[] nums = {10,5,12,6,8,3};
        bubbleSort(nums);

    }
    public static void bubbleSort(int[] arr){
        //内层循环 控制比较的次数
        for (int i = 0; i < arr.length-1; i++) {
            System.out.print("第"+i+"轮\t\t");
            //内层循环 控制比较的次数
            for (int j = 0; j <arr.length-1-i ; j++) {
                System.out.print("第"+j+"次\t");
            }
            System.out.println();
        }
    }
}
//第0轮		第0次	第1次	第2次	第3次	第4次	
//第1轮		第0次	第1次	第2次	第3次	
//第2轮		第0次	第1次	第2次	
//第3轮		第0次	第1次	
//第4轮		第0次	

总结

public class newArray {
    public static void main(String[] args) {
        int[] nums={10,5,12,8,6};
        selectSort(nums);
        for (int i = 0; i < nums.length; i++) {
            System.out.print(nums[i]+"\t");
        }
    }
    //冒泡排序 口诀:N个数字来排列,两两比较小de靠前,外层循环n-1 ,内层循环n-1-i
    public static void bubbleSort(int[] arr){
        //外层循环控制轮数
        for (int i = 0; i < arr.length-1; i++) {
            //内层循环 控制比较的次数
            for (int j = 0; j < arr.length-1-i; j++) {
                // j和j+1 交换
                if(arr[j]>arr[j+1]) {    //arr[j]<arr[j+1] 从大到小
                    int t = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = t;
                }
            }
        }
    }
}
冒泡排序基本实现与优化
//基本实现
public static int[] sort1(int[] arr) {
    for (int j = 0; j < arr.length; j++) {
        for (int i = 0; i < arr.length - 1; i++) {
            if(arr[i] > arr[i+1]) {
                int temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }
    }
    return arr;
}
  • 优化1:次数优化

    public static int[] sort2(int[] arr) {
        for (int j = 0; j < arr.length; j++) {   //轮数
            for (int i = 0; i < arr.length - 1 - j; i++) {//每一轮的次数
                if(arr[i] > arr[i+1]) {
                    int temp = arr[i];
                    arr[i] = arr[i+1];
                    arr[i+1] = temp;
                }
            }
        }
        return arr;
    }
    
  • 优化2:轮数优化

    public static int[] sort3(int[] arr) {
        for (int j = 0; j < arr.length - 1; j++) { //轮数
            //假设这一轮已经拍好序了
            boolean flag = true;
            for (int i = 0; i < arr.length - 1 - j; i++) {//每一轮次数
                if(arr[i] > arr[i+1]) {
                    flag = false;
                    int temp = arr[i];
                    arr[i] = arr[i+1];
                    arr[i+1] = temp;
                }
            }
            if(flag) {
                break;
            }
        }
        return arr;
    }
    
7.7.2 选择排序

选择排序升序思路:

  • 1、将当前这个数,与他后面每一个数字比较,选择最小的那个数,交换到当前位置
  • 2、循环选择当前位置上的数
public static int[] sort1(int[] arr) {
    for (int j = 0; j < arr.length-1; j++) {
        //选择下标为0的位置
        int min = j;
        //将当前这个数与后面的每一个数进行比较
        for (int i = j+1; i < arr.length; i++) {
            if(arr[min] > arr[i]) {
                min = i;
            }
        }
        //arr[j]   arr[min]
        if(min != j) {
            int temp = arr[j];
            arr[j] = arr[min];
            arr[min] = temp;
        }
    }
    return arr;
}

细分示例:

public class newArray {
    //选择排序
    public static void selectSort(int[] arr){
        //外层循环控制轮数
        for (int i = 0; i < arr.length-1; i++) {
            int min=i;//保存最小元素的下标
            for (int j = i+1; j < arr.length; j++) {
                if(arr[j]<arr[min]){
                    min=j;//最小的下标
                }
            }
            if(min!=i){
                int t=arr[i];
                arr[i]=arr[min];
                arr[min]=t;
            }
        }
    } 
}
7.7.3 Arrays工具类排序方法
public class Demo03 {
	//Arrays类提供的数组排序的方法
	public static void main(String[] args) {
		int[] arr = {11,22,33,31,41,15};
		
		//Arrays类提供的数组排序的方法     快速排序
		Arrays.sort(arr);
		
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
		System.out.println("==============================================");
		String[] names = {"cxk","rose","lihua","lilei","zhaosi"};
		
		Arrays.sort(names);

		for (int i = 0; i < names.length; i++) {
			System.out.print(names[i]+"\t");
		}
		
	}
}

API 工具类

Arrays工具类的使用

public class Demo {
    public static void main(String[] args) {
        int[] nums={15,10,3,20,13,1,20,35,39,28,18,22};
        //1 排序 Arrays.sort();
        Arrays.sort(nums);
        //2 字符串形式 Arrays.toString();
        String s=Arrays.toString(nums);
        System.out.println(s);
        //3 二分查找
        int pos=Arrays.binarySearch(nums,1);
        System.out.println(pos>=0?"找到了":"没有找到");
        //4 复制数组
        int[] newArr=Arrays.copyOf(nums,nums.length*2);
        System.out.println(Arrays.toString(newArr));
        //截取数组前num项
        int[] newArr= Arrays.copyOf(nums,5);
        System.out.println(Arrays.toString(newArr));
        //5 填充,fill
        Arrays.fill(nums,100);
        System.out.println(Arrays.toString(nums));
    }
}
补充 JDK API 1.6
7.8 二分查找法

二分查找法(折半查找法)

  • 前提:数组中的元素是有序的
  • 思路:
    • 首先找到数组中的中间的元素,与要查找元素进行比较,如果相等,那么就直接找到了
    • 如果比中间的元素大,那么表示查找元素在中间值的右边。所以最小值的下标等于中间值的下标+1
    • 如果比中间的元素小,那么表示查找元素在中间值的左边。所以最大值的下标等于中间值的下标-1
//二分查找法
public static int search2(int[] arr,int num) {
    //1、获取最小、大值的下标
    int min = 0;
    int max = arr.length -1;

    while(min <= max) {
        //2、获取中间值的下标
        int middle = (min + max) / 2;

        //3、将要查找的数字与中间值做比较
        if(num > arr[middle]) {
            min = middle +1;
        }else if(num < arr[middle]) {
            max = middle -1;
        }else {
            return middle;
        }
    }
    return -1;
}

对比:顺序查找与二分查找

import java.util.Scanner;
public class Demo {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        System.out.println("请输入您要查找的元素");
        int n=input.nextInt();
        //int pos=sequenceSearch(n);
        int pos=binarySearch(n);
        System.out.println(pos>=0?"找到了":"没有找到");
    }
    //顺序查找:从第一个元素遍历到最后一个元素,查找符合要求的。
    public static int sequenceSearch(int key){
        int[] arr=new int[]{15,2,8,20,3,28,30,16,22};
        for (int i = 0; i < arr.length; i++) {
            if(key==arr[i]){
                return i;
            }
        }
        return -1;
    }
    //二分查找:二分查找前提,数组是有序的。
    //每次从中间开始查找,如果比中间数字小,在左边查找,如果比中间数字大,在右边查找,依次再进行二分查找,直到找到为止。
    public static int binarySearch(int key){
        int[] arr=new int[]{1,3,5,8,10,15,22,23,25,30,35,50,55,60};
        int low=0;
        int upper=arr.length-1;
        while(low<=upper){
            int mid=(low+upper)>>>1;
            if(key<arr[mid]){
                upper=mid-1;
            }else if(key>arr[mid]){
                low=mid+1;
            }else{
                return mid;
            }
        }
        return -1;
    }
 
}
7.9 二维数组
  • 一维数组中的每一个元素,存储的是一个数据
  • 二维数组中的每一个元素,存储的是一个一维数组
public class newArray {
    public static void main(String[] args) {
        //声明二维数组
        int[][] nums1=new int[][]{ {10,20,30},{40,50,60} };
        int[][] nums2=new int[2][3];// 第一维数组长度是2, 第二维数组长度是3

        nums2[0][0]=100;
        nums2[0][1]=200;
        nums2[0][2]=300;
        nums2[1][0]=400;
        nums2[1][1]=500;
        nums2[1][2]=600;

        //输出数组长度
        System.out.println(nums2.length);
        System.out.println(nums2[0].length);
        System.out.println(nums2[1].length);

        //遍历二维数组
        for (int i = 0; i < nums2.length; i++) {    //第一维数组
            for (int j = 0; j < nums2[i].length; j++) {     //第二维数组
                System.out.print(nums2[i][j]+"\t");
            }
            System.out.println();
        }
        //创建不规则的二维数组
        int[][] nums3=new int[][]{{5,6,10},{3,20,22,50,80}};
        int[][] nums4=new int[2][]; //第一维长度是2, 每个元素null
        nums4[0]=new int[]{5,6,10};
        nums4[1]=new int[]{3,20,22,50,80};

    }
}

//        2
//        3
//        3
//        100	200	300
//        400	500	600
7.9.1 创建二维数组

静态初始化:

  • 语法1:数据类型[][] 数组名 = {{元素1,元素2,…},{元素1,元素2,…},…};
  • 语法2:数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2,…},{元素1,元素2,…},…};

动态初始化

  • 语法:数据类型[][] 数组名 = new 数据类型[ 二维数组的长度] [一维数组的长度];
  • 注意:二维数组的长度必须要定义,一维数组的长度可以暂时不定义
7.9.2 二维数组的使用
int[][] arr = new int[3][];  
//操作数组  存储或者获取
//注意:在使用之前必须先要对一维数组进行初始化
//arr[0][0] = 11;错误
arr[0] = new int[2];
arr[0][0] = 11;
arr[0][1] = 22;

arr[1] = new int[1];
arr[1][0] = 33;

arr[2] = new int[3];
arr[2][0] = 44;
arr[2][1] = 55;
arr[2][2] = 66;

//获取二维数组的长度
System.out.println(arr.length);
7.9.3 二维数组的遍历
//二维数组的遍历
for (int i = 0; i < arr.length; i++) {
    for (int j = 0; j < arr[i].length; j++) {
        System.out.println(arr[i][j]);
    }
}
7.9.4 二维数组的应用

用二维数组实现杨辉三角

// 使用二维数组实现杨辉三角
public class Demo {
    public static void main(String[] args) {
        rectangle();
    }
    public static void rectangle(){
        int[][] arr=new int[5][];
        for (int i = 0; i < arr.length; i++) {
            arr[i]=new int[i+1];//第二维数组初始化
            //空格 %s System.out.printf()
            //元素赋值
            for (int j = 0; j < arr[i].length; j++) {
                if(j==0||i==j){
                    arr[i][j]=1;
                }else{
                    arr[i][j]=arr[i-1][j-1]+arr[i-1][j];
                }
                System.out.print(arr[i][j]);//输出
            }
            System.out.println();
        }
    }
}
7.10 可变参数

可变参数:jdk1.5之后的新语法

语法: 数据类型… 参数名

特点:

  • 1、带有可变参数方法的调用的时候,实参个数,可以是0个或者是多个
  • 2、可变参数只能放在参数列表的最后(一个方法只能有一个可变参数)
  • 3、可变参数可以当做数组来使用,也可以将数组作为参数

场景:不确定参数个数的时候

​ 案例:根据用户传入的数字,进行求和,数字个不确定

//案例:根据用户传入的数字,进行求和,数字个不确定
public static int sum(int... arr) {
    int sum = 0;
    for (int i = 0; i < arr.length; i++) {
        sum = sum + arr[i];
    }
    return sum;
}

可变长参数

public class newArray {
    public static void main(String[] args) {
        //传递数组元素
        printArry(100,22,33,44,55,66);
    }
    //可变长参数:可接收多个同类型实参,个数不限,使用方式与数组相同。
	//优点:比数组更加灵活
	//要求:只能方法参数列表最后,只能有一个
    public static void printArry(int x,int ...arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+"\t");
        }
    }
}
//22	33	44	55	66
7.10.1 可变参数方法的定义
public static void m1(int... a) {
    System.out.println(a[0]);
    System.out.println(a[1]);
}
7.10.2 带有可变参数方法的调用
//方式1
m1(1,2,3,4,5);
//方式2:
int[] arr = {1,2,3};
m1(arr);
7.11 值传递和应用传递

值传递和引用传递

  • 值传递:传递的是值,所以原来的值本身不会改变,所有的基本类型+String都属于值传递
  • 引用传递:传递的是地址,所以会对原来的内容有影响,所有引用数据类型都属于引用传递
public class Demo {
    public static void main(String[] args) {
        /*
        int x=10,y=20;
        swap(x,y);
        System.out.println("x:"+x+" y:"+y);
        */
        int[] nums={80,82,85,79,75};
        printArray(nums);
        System.out.println("--------------");
        for (int num : nums) {
            System.out.println(num);
        }
    }
    //基本类型作为方法的参数
    public static void swap(int a,int b){
        System.out.println("交换前 a:"+a+" b:"+b);
        a=a^b;
        b=a^b;
        a=a^b;
        System.out.println("交换后 a:"+a+" b:"+b);
    }
    //数组作为方法的参数
    public static void printArray(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            arr[i]=arr[i]+5;
            System.out.println(arr[i]);
        }
    }
}

public class newArray {
    public static void main(String[] args) {
        int [] arr= {89,85,92,85,84,88};
        arr = expand(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+"\t");  //89	85	92	85	84	88	0	0	0	0	0	0
        }
    }
    //数组类型作为方法的返回值,数组扩容
    public static int[] expand(int[] old){
        //1.创建一个长度大于原数组的新数组
        int[] newArray =new int[old.length*2];
        //2.复制原数组数据
        for (int i = 0; i < old.length; i++) {
            newArray[i]=old[i];
        }
        //3.返回新数组地址
        return newArray;
    }
}
//调用基本类型返回值的方法时,方法执行后,返回的是数据;
//
//调用引用类型返回值的方法时,方法执行后,返回的是地址
public class Demo {
	public static void main(String[] args) {
        //通过方法形式的传递
//		int a = 10;
//		System.out.println("传递之前a的值为:"+a);
//		m1(a);
//		System.out.println("传递之后a的值为:"+a);
//		
//		String s = "hello";
//		System.out.println("传递之前s的值为:"+s);
//		m2(s);
//		System.out.println("传递之后s的值为:"+s);
//		
//		double[] d = {1,2,3};
//		System.out.println("传递之前d[0]的值为:"+d[0]);
//		m3(d);
//		System.out.println("传递之后d[0]的值为:"+d[0]);
		
		
        //通过变量形式的传递
		int a = 10;
		int b = a; 
		b = 20;
		System.out.println(a);
		
		String s = "a";
		String s1 = s;
		s1 = "b";
		System.out.println(s);
		
		
		int[] arr1 = {1,2,3};
		int[] arr2 = arr1;
		arr2[0] = 100;
		System.out.println(arr1[0]);
		
		
	}
	public static void m1(int a) {
		a = 20;
	}
	public static void m2(String s) {
		s = "world";
	}
	public static void m3(double[] d) {
		d[0] = 100;
	}
}
7.12 数组的增删改查
7.12.1 增加数据

​ 增加数据分为两种添加方式“一种叫做静态添加和一种叫做动态添加”

  • 一般静态添加使用较少,它的操作还就是在数组的时候,直接数组中存储数据

    int[] arr = new int[]{1,2,3,4,5,6,7};
    int[] arr2 = {1,2,3,4,5,5,6,7};
    
  • 动态添加,键盘输入数据、随机数、文件读取内容之后存储、数据库操作之后存储

    键盘输入和随机数据使用较多

    import java.util.Scanner;
    
    /**
     * @author yinying
     * @date 2023/1/10 12:21
     * @poject JavaDemo
     */
    public class newArray {
        public static void main(String[] args) {
            //定义一个int类型数组,数组的长度为10
            int[] arr = new int[10];
            //1.随机数赋值
            for(int i = 0 ; i<arr.length;i++){
                arr[i] = (int)(Math.random()*100);
            }
            //或者
            //2.通过控制台输入
            Scanner input = new Scanner(System.in);
            for(int i = 0 ; i<arr.length;i++){
                arr[i] = input.nextInt();
            }
        }
    }
    
7.12.2 查找和修改数据(转7.7.2)

数组中查找某个元素是否存在,一共有两种方式“线性(顺序)查找 和 二分(折半)查找”
单从效率而言“二分查找远远高于线性查找”,从书写代码而言“线性查找要远远简单于二分查找”
线性(顺序)查找执行原理:就是从数组第一个元素逐一向后查找每一个元素
线性查找最优解 1次 【数组第一个元素就是要查找的元素】
线性查找最坏解 数组长度次数 【数组最后一个元素是要查找的元素】
线性查找最大有点就是简单易用,效率确实不高

import java.util.Arrays;
import java.util.Scanner;

/**
 * @author yinying
 * @date 2023/1/10 17:11
 * @poject JavaDemo
 */
public class newArray {
    public static void main(String[] args) {
        //1.提供一个int类型数组,数组长度10
        int[] arr = new int[10];
        //2.通过随机数向数组中进行赋值操作
        for(int i = 0 ; i<arr.length;i++) {
            arr[i] = (int) (Math.random() * 100);
        }
        System.out.print("arr数组中存储数据是:[");
        for(int i =0 ; i<arr.length;i++){
            if(i != arr.length-1){
                System.out.print(arr[i]+",");
            }else{
                System.out.println(arr[i]+"]");
            }
        }
        System.out.println("请输入您要在arr数组中要查找的数据:");
        Scanner input = new Scanner(System.in);
        int num = input.nextInt();
        //提供线性(顺序)查找,判断要查找数据是否存在在当前的数组中
        for(int i = 0 ;i<arr.length;i++){
            if(arr[i] == num){
            //提供修改
            // arr[i] = 10000;
            //提示找到了数据
                System.out.println("您输入数据是在数组中存储的下标为:"+i);
                return;
            }
        }
        System.out.println("没有找到数据");
    }
}
7.12.3 删除

在没有使用数组的“减容”之前,数组中是没有真正删除的

“减容”—根据删除元素个数动态缩小数组容量(大小/长度)

如何在数组中执行删除操作?
根据中存储元素类型来决定,如果数组中存储的是基本数据类型,采用后一个数据覆盖前一位数据的方式进行删除,并记录删除个数以便在打印时,可以不输出多余数据【这个操作不是”减容“,数组长度不会改变】,如果数组中存储的是引用数据类型,依旧会采用后一个数据覆盖前一个数据方式,会在最后一个数据位置添加 null值,或者直接要删除的赋值为null,并记录删除个数以便在打印中,不输出多余的数据。

package priv.yinying.javademo;

import java.util.Arrays;
import java.util.Scanner;

/**
 * @author yinying
 * @date 2023/1/10 19:33
 * @poject JavaDemo
 */
public class newArray {
    public static void main(String[] args) {
        //1.提供一个int类型数存储10个元素
        int[] arr = new int [10];
        //2.提供动态赋值同时打印数组中数据
        System.out.print("arr数组中存储的数据[");
        for(int i = 0 ; i<arr.length;i++){
            arr[i] = (int)(Math.random()*100);
            if(i != arr.length-1){
                System.out.print(arr[i]+",");
            }else{
                System.out.println(arr[i]+"]");
            }
        }
        System.out.println("删除之前arr数组的长度:"+arr.length);
        //3.提供外界输入的数据进行删除操作
        System.out.println("请输入您要删除的数据:");
        Scanner input = new Scanner(System.in);
        int num = input.nextInt();
        //提供一个变量存储删除数据的个数
        int count = 0;
        //3.1提供一个循环遍历数组寻找要删除数据
        for(int i = 0; i<arr.length;i++){
            if(arr[i] == num){
        //如果if语句成立就证明数组中是存在要删除的数据的
        //3.2在提供一个循环使用删除数据位置的后一个数据向前覆盖操作
                for(int j = i;j<arr.length-1;j++){
                    arr[j] = arr[j+1];
                }
                //循环结束之后就证明删除完成,统计计数
                count++;
            }
        }
        //真删除【减容】
        //在创建一个数组存储删除之后的数据
        /* int[] temp = new int[arr.length-count];
        for(int i = 0 ; i<arr.length-count;i++){
        temp[i] = arr[i];
        }
        //将存储着真删除数据的数据引用赋值给arr
        arr = temp;
        temp = null; //删除temp与堆中关联
        //在打印arr数组就是真删除,长度也改变了
        System.out.println("真删除之后arr数组的长度:"+arr.length);*/
        //4.提供打印操作
        System.out.print("删除数组中数之后arr数组中元素:[");
        for(int i = 0 ; i<arr.length-count;i++){
            if(i != arr.length-1-count){
                System.out.print(arr[i]+",");
            }else{
                System.out.println(arr[i]+"]");
            }
        }
        System.out.println("删除之后arr数组的长度:"+arr.length);
    }
}
(补充)调试技巧

使用IDEA的调试技巧,帮助开发人员理解程序执行过程,需要两个步骤:

  • 添加断点
  • 单步执行

快捷键:

  • F7单步进入
  • Step Into F8单步跳过
  • Step OverF9继续执行 Resume

查看变量窗口、断点窗口

插入排序和快速排序 (后续扩展补充)
;