一. 一维数组
1. 数组概念
存储同种数据类型的容器 ==> 内存中一块连续的空间
int[] arr = new int[length];
数组 类 接口 都是引用数据类型
引用的是堆内存中的地址值 arr ==> 地址值
new 关键字会在堆内存中开辟一块空间
索引:帮助我们取出数组中的元素
特点: 从0开始 连续且递增1
2. 静态初始化
int[] arr = new int[]{1,2,3}; 简写格式 int[] arr = {1,2,3};//简写格式虽然我们没写new 但是JVM会帮我们补上 也是在堆内存中开辟空间
3. 默认值
数组中是有默认值的
int => 0 double 0.0 boolean false char '' 引用数据类型默认值为null
4. 数组:遍历
遍历:取出数组中元素的过程
arr.length 动态获取数组长度
for(int i = 0;i < arr.length; i++){ sout(arr[i]); }
⚫例题:使用Random产生10个随机数[22-888],然后放到一个数组中,
要求:1.打印数组元素 2.将数组中是3的整倍数的元素打印出来
import java.util.Random; public class demo3 { public static void main(String[] args) { int[] arr = new int[10]; for (int i = 0; i <10 ; i++) { Random r = new Random(); arr[i] = r.nextInt(867) + 22; System.out.print(arr[i]+" "); } System.out.println(); for (int i = 0; i < arr.length; i++) { if(arr[i]%3==0){ System.out.print(arr[i]+" "); } } } }
⚫定义一个长度为5的int数组arr,提示用户输入5个1-60(需要判断)之间的数字作为数组元素 生成2-10(包含2和10)之间的随机数num; 遍历数组arr,筛选出数组中不是num倍数的元素输出
public static void main(String[] args) { int[] arr = new int[5]; Scanner sc = new Scanner(System.in); for (int i = 0; i < arr.length; i++) { System.out.println("请输入第" + (i + 1) + "个1-60之间的数"); int X = sc.nextInt(); if (X >= 1 && X <= 60) { arr[i] = X; } else { i--; System.out.println("输入错误请重新输入"); } } Random r = new Random(); int num = r.nextInt(9) + 2; System.out.println("num = " + num); for (int i = 0; i < arr.length; i++) { if (arr[i]%num != 0) { System.out.print(arr[i]+" "); } } } }
5. 数组:求和
⚫键盘录入5个整数,存储到数组中,并对数组求和
public class demo7 { public static void main(String[] args) { // 定义一个求和变量,准备记录累加后的结果 int sum=0; // 动态初始化一个长度为5的int数组,准备存储键盘录入的数值 int[] arr= new int[5]; for (int i = 0; i < arr.length; i++) { Scanner sc = new Scanner(System.in); System.out.println("请输入第"+ (i+1)+"个整数"); // 将键盘录入的数值存储到数组中 arr[i]= sc.nextInt(); } //遍历数组,取出每一个元素,并求和 for (int i = 0; i < arr.length; i++) { sum += arr[i]; } //输出总和。注意sout要在for循环之外 System.out.println(sum); } }
⚫键盘录入6个整数, 将其存入到数组中
需求一: 统计数组中所有的奇数之和, 并将结果打印到控制台上.
需求二: 将数组元素按照指定格式打印.
例如: 数组元素为: int[] arr = {11, 22, 33, 44, 55}; 打印格式为: [11, 22, 33, 44, 55]
public class demo1{ public static void main(String[] args) { int[] arr = new int[6]; Scanner sc = new Scanner(System.in); for (int i = 0; i < 6 ; i++) { System.out.println("请输入第"+(i+1)+"个整数:"); arr[i] = sc.nextInt(); } int sum = 0; for (int i = 0; i < arr.length; i++) { if(arr[i] %2==1){ sum+=arr[i]; } } System.out.println(sum); //遍历数组打印 System.out.print("["); for (int i = 0; i < arr.length; i++) { if (i != arr.length-1) { System.out.print(arr[i] + ","); } else { System.out.print(arr[i]); } } System.out.print("]"); } }
⚫定义一个用于存放班级分数的数组 int[] score = {80,90,85,90,58,88,49,93,98,75};
1.求出班级不及格人数(分数低于60分的就是不及格)
2.求出班级的总分数
3.求出班级的平均分
public class demo1 { public static void main(String[] args) { int[] score = {80,90,85,90,58,88,49,93,98,75}; //求出班级不及格人数 int low = 0; int index = -1; for (int i = 0; i < score.length; i++) { if(score[i]<60){ index=1; low += index;} } System.out.println(low); //求出班级的总分数 int sum=0; for (int i = 0; i < score.length; i++) sum += score[i]; System.out.println(sum); //求出班级的平均分 Double average= sum* 1.0/ score.length; System.out.println(average); } }
6. 数组:查找
获取数组中索引 //假设不存在与数组之中 int index = -1; //循环比较 for(int i = 0;i < arr.length; i++){ if(num == arr[i]){ index = i; } } if(index == -1){ sout("不存在"); }else{ sout(index); }
⚫已知一个数组 arr = {19, 28, 37, 46, 50}; 键盘录入一个数据,查找该数据在数组中的索引,并在控制台输出找到的索引值。
public class demo5 { public static void main(String[] args) { int[] arr = {19, 28, 37, 46, 50}; Scanner sc = new Scanner(System.in); System.out.println("请输入一个整数"); int num= sc.nextInt(); //1.假设数字不存在于集合之中:定义一个索引变量,初始值为-1 int index=-1; //2.遍历数组,获取到数组中的每一个元素 for (int i = 0; i < arr.length; i++) { //3.判断数组中是否存在该变量 if (num == arr[i]) { index = i; System.out.println("该元素存在于"+index+"位置"); } } if(index==-1){ System.out.println("该元素不在数组之中"); } } }
7. 数组:取最值
//假设数组第一值为最值 int max = arr[0]; //循环遍历比较 for(int i = 0;i < arr.length; i++){ //进行比较 if(max < arr[i]){ max = arr[i]; } }
⚫案例:评委打分
需求:在编程竞赛中,有6个评委为参赛的选手打分,分数为0-100的整数分。
选手的最后得分为:去掉一个最高分和一个最低分后的4个评委平均值 (不考虑小数部分)。
import java.util.Scanner; public class demo6 { public static void main(String[] args) { //1. 动态初始化一个数组。 int[] arr = new int[6]; //2. 键盘录入 Scanner sc= new Scanner(System.in); //3.定义一个统计变量 int sum = 0; //4.循环存入分值 for (int i =0 ; i < arr.length; i++) { System.out.println("请输入第" + (i + 1) + "位评委的分数"); int score = sc.nextInt(); //5.判断分值是否在0~100之间 if (score >= 0 && score <= 100) { arr[i] = score; sum += arr[i]; } else { i--; //6.让评委重新打分 System.out.println("输入错误,请重新输入"); } } //7.求最大值 int max = arr[0]; for (int i = 0; i < arr.length; i++) { if(max<arr[i]){ max=arr[i]; } } //8.求最小值 int min = arr[0]; for (int i = 0; i < arr.length; i++) { if(min>arr[i]){ min=arr[i]; } } double average= (sum-min-max)*1.0/4;; System.out.println(average); } }
二. 二维数组
1. 二维数组概述
二维数组是一维数组的容器。
二维数组储存的是一维数组的元素地址。
2. 二维数组的静态初始化
格式:数据类型[][]变量名 = new 数据类型[m][n]; //m表示这个二维数组,可以存放多少个一维数组 //n表示每一个一维数组,可以存放多少个元素 范例:int [ ] [ ] arr = new int [ 2 ][ 3 ]; //该数组可以存放2个一维数组,每个一维数组中可以存放3个int类型元素
3. 向二维数组中储存元素
int[][]arr = new int [3][3]; //把数值存入二维数组 arr[0][0]=11; arr[0][1]=22; arr[0][2]=33; arr[1][0]=11; arr[1][1]=22; arr[1][2]=33; arr[2][0]=11; arr[2][1]=22; arr[2][2]=33; //把已有的一维数组存入二维数组 int[]arr1 = {11,22,33}; int[]arr2 = {44,55,66}; int[]arr3 = {77,88,99}; arr[0] = arr1; arr[1] = arr2; arr[2] = arr3;
4. 取出二维数组的元素
int[][] arr ={{11,22,33},{44,55},{66,77,88,99}}; //取出二维数组在堆内存中的地址值 System.out.println(arr); //输出结果为:[[I@10f87f48 //取出二维数组中第1个一维数组的地址值 System.out.println(arr[0]);//输出结果为:[I@b4c966a //取出二维数组中第1个一维数组的第一个值 System.out.println(arr[0][0]);//输出结果为:11
5. 二维数组的遍历
双重for循环
public class demo1 { public static void main(String[] args) { int[][]arr = {{11,22,33},{44,55,66},{77,88,99}}; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { System.out.print(arr[i][j]+" "); } } } }
⚫已知一个二维数组 arr = { {11 , 22 , 33} , {33 , 44 , 55} ,{77,88,99}};
遍历该数组,取出所有元素并打印
public class demo1 { public static void main(String[] args) { int[][]arr = {{11,22,33},{44,55,66},{77,88,99}}; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { System.out.print(arr[i][j]+" "); } } } }
6.二维数组求和
public class demo2 { public static void main(String[] args) { int[][]arr = {{11,22,33},{44,55},{66,77,88,99}}; int sum = 0; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { sum += arr[i][j]; } } System.out.println(sum); } }
案例:年销售额求和
⚫某公司季度和月份统计的数据如下:单位(万元)
第一季度:22,66,44 第二季度:77,33,88 第三季度:25,45,65 第四季度:11,66,99
①:定义求和变量,准备记录最终累加结果
②:使用二维数组来存储数据,每个季度是一个一维数组,再将4个一维数组装起来
③:遍历二维数组,获取所有元素,累加求和
④:输出最终结果
public class demo2 { public static void main(String[] args) { int[][]arr = {{22,66,44},{77,33,88},{25,45,65}}; int sum = 0; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { sum += arr[i][j]; } } System.out.println(sum); } }
三. 数组的高级操作
1. 二分查找
-
二分查找概述
查找指定元素在数组中的位置时,以前的方式是通过遍历,逐个获取每个元素,看是否是要查找的元素,这种方式当数组元素较多时,查找的效率很低
二分查找也叫折半查找,每次可以去掉一半的查找范围,从而提高查找的效率
-
需求
在数组{1,2,3,4,5,6,7,8,9,10}中,查找某个元素的位置
-
实现步骤
-
定义两个变量,表示要查找的范围。默认min = 0 ,max = 最大索引
-
循环查找,但是min <= max
-
计算出mid的值
-
判断mid位置的元素是否为要查找的元素,如果是直接返回对应索引
-
如果要查找的值在mid的左半边,那么min值不变,max = mid -1.继续下次循环查找
-
如果要查找的值在mid的右半边,那么max值不变,min = mid + 1.继续下次循环查找
-
当min > max 时,表示要查找的元素在数组中不存在,返回-1.
-
-
代码实现
public class MyBinarySearchDemo { public static void main(String[] args) { int [] arr = {1,2,3,4,5,6,7,8,9,10}; int number = 11; //1,我现在要干嘛? --- 二分查找 //2.我干这件事情需要什么? --- 数组 元素 //3,我干完了,要不要把结果返回调用者 --- 把索引返回给调用者 int index = binarySearchForIndex(arr,number); System.out.println(index); } private static int binarySearchForIndex(int[] arr, int number) { //1,定义查找的范围 int min = 0; int max = arr.length - 1; //2.循环查找 min <= max while(min <= max){ //3.计算出中间位置 mid int mid = (min + max) >> 1; //mid指向的元素 > number if(arr[mid] > number){ //表示要查找的元素在左边. max = mid -1; }else if(arr[mid] < number){ //mid指向的元素 < number //表示要查找的元素在右边. min = mid + 1; }else{ //mid指向的元素 == number return mid; } } //如果min大于了max就表示元素不存在,返回-1. return -1; } }
-
注意事项
有一个前提条件,数组内的元素一定要按照大小顺序排列,如果没有大小顺序,是不能使用二分查找法的
2. 冒泡排序
-
冒泡排序概述
一种排序的方式,对要进行排序的数据中相邻的数据进行两两比较,将较大的数据放在后面,依次对所有的数据进行操作,直至所有数据按要求完成排序
如果有n个数据进行排序,总共需要比较n-1次
每一次比较完毕,下一次的比较就会少一个数据参与
-
代码实现
public class MyBubbleSortDemo2 { public static void main(String[] args) { int[] arr = {3, 5, 2, 1, 4}; //1 2 3 4 5 bubbleSort(arr); } private static void bubbleSort(int[] arr) { //外层循环控制的是次数 比数组的长度少一次. for (int i = 0; i < arr.length -1; i++) { //内存循环就是实际循环比较的 //-1 是为了让数组不要越界 //-i 每一轮结束之后,我们就会少比一个数字. for (int j = 0; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } printArr(arr); } private static void printArr(int[] arr) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } }
3. 递归
3.1 递归【应用】
-
递归的介绍
-
以编程的角度来看,递归指的是方法定义中调用方法本身的现象
-
把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
-
递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算
-
-
递归的基本使用
public class MyFactorialDemo2 { public static void main(String[] args) { int sum = getSum(100); System.out.println(sum); } private static int getSum(int i) { //1- 100之间的和 //100 + (1-99之间的和) // 99 + (1- 98之间的和) //.... //1 //方法的作用: 求 1- i 之间和 if(i == 1){ return 1; }else{ return i + getSum(i -1); } } }
-
递归的注意事项
-
递归一定要有出口。否则内存溢出
-
递归虽然有出口,但是递归的次数也不宜过多。否则内存溢出
-
3.2 递归求阶乘【应用】
-
案例需求
用递归求5的阶乘,并把结果在控制台输出
-
代码实现
public class DiGuiDemo01 { public static void main(String[] args) { //调用方法 int result = jc(5); //输出结果 System.out.println("5的阶乘是:" + result); } //定义一个方法,用于递归求阶乘,参数为一个int类型的变量 public static int jc(int n) { //在方法内部判断该变量的值是否是1 if(n == 1) { //是:返回1 return 1; } else { //不是:返回n*(n-1)! return n*jc(n-1); } } }
-
内存图
斐波那契数列指的是这个数列从第3项开始,每一项都等于前两项之和。例如1,1,2,3,5,8,13,21,34,55,89 求出前10项斐波那契数列,第一项和第二项分别为0,1。
public class Demo5 { public static void main(String[] args) { int[] arr = new int[10]; for (int i = 0; i < 10; i++) { arr[i] = add(arr,i); System.out.print(arr[i]+" "); } } private static int add(int[]arr,int i){ if(i == 0){ return 0; }if(i == 1) { return 1; } else{ return (arr[i-1]) + add(arr,i-2); } } }
3.3 Arrays (应用)
-
Arrays的常用方法
方法名 说明 public static String toString(int[] a) 返回指定数组的内容的字符串表示形式 public static void sort(int[] a) 按照数字顺序排列指定的数组 public static int binarySearch(int[] a, int key) 利用二分查找返回指定元素的索引 -
示例代码
public class MyArraysDemo { public static void main(String[] args) { // public static String toString(int[] a) 返回指定数组的内容的字符串表示形式 // int [] arr = {3,2,4,6,7}; // System.out.println(Arrays.toString(arr)); // public static void sort(int[] a) 按照数字顺序排列指定的数组 // int [] arr = {3,2,4,6,7}; // Arrays.sort(arr); // System.out.println(Arrays.toString(arr)); // public static int binarySearch(int[] a, int key) 利用二分查找返回指定元素的索引 int [] arr = {1,2,3,4,5,6,7,8,9,10}; int index = Arrays.binarySearch(arr, 0); System.out.println(index); //1,数组必须有序 //2.如果要查找的元素存在,那么返回的是这个元素实际的索引 //3.如果要查找的元素不存在,那么返回的是 (-插入点-1) //插入点:如果这个元素在数组中,他应该在哪个索引上. } }
-
工具类设计思想
-
构造方法用 private 修饰
-
成员用 public static 修饰
-