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
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; }
07 Java数组与数组操作(定义+遍历+排序+增删改查)(下):https://developer.aliyun.com/article/1580202