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 数组的细节
- 数组中的每一个数据称之为数组元素
- 数组中的每一个元素都对应有一个下标
- 数组中的下标范围0~数组的长度-1
- 数组的长度通过数组名.length获取
- 数组的长度如果超出的边界会报错(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
7.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
查看变量窗口、断点窗口