161-190数组/数组的赋值/数组的拷贝/数组的反转/数组的添加/认识排序/认识查找/二维数组
一、数组应用案例
1、创建一个char类型的26个元素的数组,分别放置'A'-'Z',使用for循环访问所有元素并打印出来。提示char类型数据运算'A' + 1 => 'B'
ArrayExercise01.java
// 我的代码
public class ArrayExercise01 {
public static void main(String[] args) {
char[] letters = new char[26];
for (int i = 0; i < letters.length; i++) {
letters[i] = (char)('A' + i);
}
for (int i = 0; i < letters.length; i++) {
System.out.print(letters[i]);
}
}
}
2、请求出一个数组int[]的最大值{4, -1, 9, 10, 23},并得到对应的下标。
ArrayExercise02.java
// 我的代码
public class ArrayExercise02 {
public static void main(String[] args) {
int[] nums = {4, -1, 9, 10, 23};
int max = 0;
int maxIndex = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] >= max) {
max = nums[i];
maxIndex = i;
}
}
System.out.println("max = " + max + "\nmaxIndex = " + maxIndex);
}
}
3、请求出一个数组的和和平均值。(养鸡场)
ArrayExercise03.java
// 我的代码
public class ArrayExercise03 {
public static void main(String[] args) {
double hens[] = {10.3, 53.2, 35.2, 23, 88.35};
double sum = 0.0;
for (int i = 0; i < hens.length; i++) {
sum += hens[i];
}
System.out.println("sum = " + sum + "\navg = " + (sum / hens.length));
// sum = 210.05 avg = 42.01
System.out.println("预期结果:sum = 210.05 avg = 42.01");
}
}
// 1、老师的代码
创建一个char类型的26个元素的数组,分别放置A-Z
使用for循环访问所有元素并且打印出来
提示可以使用char类型数据运算'A' + 1 - > 'B'
思路分析:
定义一个数组char[] chars = new char[26]
因为‘A’ + 1 = ‘B’类推,所以使用for来赋值
使用for循环访问所有元素
char[] chars = new char[26];
for (int i = 0; i < chars.length; i++) {
chars[i] = (char)('A' + i);
}
又因为'A' + i最后的结果是int类型需要强制转换成char类型
最后打印输出
// 循环输出
System.out.println("===chars数组===");
for(int i = 0; i < chars.length; i++) {
System.out.print(chars[i] + " ");
}
// 2、老师的代码
请求出一个数组的最大值,并得到对应的下标
首先定义一个int数组
然后假定max = arr[0]是最大值,maxIndex = 0;
从下标1开始遍历arr,如果max < 当前元素,说明max不是真正的最大值,我们就需要max = 当前元素;
maxIndex=当前元素下标
当我们遍历这个数组arr后,max就是真正的最大值,maxIndex最大值对应的下标
int[] arr = {4, -1, 9, 10, 23};
int max = arr[0];
int maxIndex = 0;
for (int i = 1; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
maxIndex = i;
}
}
System.out.println("max = " + max + " maxIndex = " + maxIndex);
// 3、老师的代码
这里不讲了,和之前一样
二、数组赋值机制
1、基本数据类型赋值,这个值就是具体的数据,而且相互不影响。
int n1 = 2; int n2 = n1;
2、数组在默认情况下是引用传递,赋的值是地址。
如果:
int[] arr1 = {1,2,3};
int[] arr2 = arr1;
// 基本数据类型赋值,赋值方式为值拷贝
int n1 = 10;
int n2 = n1;
n2 = 80;
System.out.println("n1 = " + n1);
System.out.println("n2 = " + n2);
// 数组在默认情况下是引用传递,赋值的是地址,赋值的方式为引用拷贝
int[] arr1 = {1,2,3};
int[] arr2 = arr1;
会相互影响
arr2[0] = 10;
System.out.println("====arr1的元素====");
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}


三、数组拷贝
编写代码完成数组的拷贝,内容赋值
ArrayCopy.java
将int[] arr1 = {10, 20, 30}; 拷贝到arr2数组
// 将 int[] arr1 = {10, 20, 30}; 拷贝到arr2数组,要求数据空间是独立的。
int[] arr1 = {10, 20, 30};
// 创建一个新的数组arr2,开辟新的数据空间
// 大小为arr1.length;
int[] arr2 = new int[arr1.length];
// 遍历arr1,把每个元素拷贝到arr2对应的元素位置
for (int i = 0; i < arr1.length; i++) {
arr2[i] = arr1[i];
}
arr2[0] = 100;
System.out.println("====arr1的元素====");
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
System.out.println("====arr2的元素====");
for (int i = 0; i < arr2.length; i++) {
System.out.println(arr2[i]);
}

四、数组反转
要求:将数组的元素内容反转
ArrayReverse.java
arr {11, 22, 33, 44, 55, 66} => {66, 55, 44, 33, 22, 11}
1、方式1:通过找规律反转
2、方式2:使用逆序赋值方式
// 我的代码
public class ArrayReverse {
public static void main(String[] args) {
// 第一种方式
int[] arr = {11, 22, 33, 44, 55, 66};
int temp = 0;
for (int i = 0,j = arr.length-1; i < j; i++, j--) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
// 第二种方式
int[] arr1 = {11, 22, 33, 44, 55, 66};
int[] temp1 = new int[arr1.length];
for (int i = arr1.length-1,j = 0; i >= 0; i--, j++) {
temp1[j] = arr1[i];
}
for (int i = 0; i < temp1.length; i++) {
System.out.print(temp1[i] + " ");
}
}
}
// 老师的思路和代码
// 定义数组
int[] arr = {11, 22, 33, 44, 55, 66};
// 老师的思路
// 规律
// 1、将arr[0] 和 arr[5]进行交换 {66, 22, 33, 44, 55, 11}
// 2、将arr[1] 和 arr[4]进行交换 {66, 55, 33, 44, 22, 11}
// 3、将arr[2] 和 arr[3]进行交换 {66,55,44, 33, 22, 11}
// 4、一共要交换3次 = arr.length / 2
// 5、每次交换时,对应的下标是arr[i]和arr[arr.length-1-i]
// 代码
int temp = 0;
int len = arr.length;
for (int i = 0; i < len / 2; i++) {
temp = arr[len - 1 - i];
arr[len - 1 - i] = arr[i];
arr[i] = temp;
}
System.out.println("====翻转后数组====");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
// 第二种方式思路分析
// 定义数组
int[] arr = {11, 22, 33, 44, 55, 66};
// 使用逆序赋值的方式
// 1、首先创建一个新的数组arr2,大小是arr.length
// 2、然后逆序遍历arr,将每个元素拷贝到arr2的元素中,顺序拷贝
// 3、加上一个循环变量便于分析
int[] arr2 = new int[arr.length];
// 逆序遍历arr
for (int i = arr.length - 1,j = 0; i >= 0; i--, j++) {
arr2[j] = arr[i];
}
// 4、当for循环结束,arr2就是一个逆序的数组
// 5、让arr指向arr2的数据空间,这个时候arr原来的数据空间没有变量引用就会被当作垃圾进行销毁。
arr = arr2;
System.out.println("====arr的元素情况====");
// 6、输出arr看看
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
第二种方式内存分析
五、数组的添加
数组的添加
要求:实现动态的给数组添加元素效果,实现对数组的扩容。ArrayAdd.java
1、原始数组使用静态分配 int[] arr = {1, 2, 3};
2、增加的元素,直接放在数组的最后 arr = {1, 2, 3, 4}
3、用户可以通过如下方法来决定是否继续添加,添加成功,是否继续?y/n
课后练习题:ArrayReduce.java
有一个数组{1, 2, 3, 4, 5},可以将该数组进行缩减,提示用户是否继续缩减,每次缩减最后哪个元素,当只剩下最后一个元素,提示,不能再缩减。
// 1、数组扩容的思路
1、定义初始数组 int[] arr = {1,2,3};
2、定义一个新的数组int[] arrNew = new int[arr.length+1];
3、遍历arr数组,依次将arr的元素拷贝到arrNew数组
4、将要添加的元素赋值给arrNew[arrNew.length-1] = 4;
5、让arr指向arrNew,arr = arrNew;自动将原来的arr数组销毁。
int[] arr = {1, 2, 3};
int[] arrNew = new int[arr.length + 1];
for (int i = 0; i < arr.length; i++) {
arrNew[i] = arr[i];
}
arrNew[arrNew.length - 1] = 4;
arr = arrNew;
System.out.println("====arr扩容后元素情况====");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
如果想要实现用户能够动态的添加可以创建Scanner接收用户的输入,判断用户是否要继续添加。因为这里不确定用户什么时候不想要添加了,需要使用死循环,加上break的方式,并且这里使用的是是否继续添加,所以一开始就可以添加,所以这里可以使用Do while循环来做。
do {
int[] arrNew = new int[arr.length + 1];
for (int i = 0; i < arr.length; i++) {
arrNew[i] = arr[i];
}
System.out.println("请输入你要添加的元素");
int addNum = myScanner.nextInt();
arrNew[arrNew.length-1] = addNum;
arr = arrNew;
System.out.println("====arr扩容后元素情况====");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println("是否继续添加y/n");
char key = myScanner.next().charAt(0);
if (key == 'n') {
break;
}
}while(true);
总结:数组的扩容是比较慢的,后面会使用链表的方式进行扩容
因为数组扩容的时候每次都需要创建一个新的数组进行拷贝,如果这个数组非常大就会耗时
课后练习题:ArrayReduce.java
有一个数组{1, 2, 3, 4, 5},可以将该数组进行缩减,提示用户是否继续缩减,每次缩减最后哪个元素,当只剩下最后一个元素,提示,不能再缩减。
// 我的代码
import java.util.Scanner;
public class ArrayReduce {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] arr = {1, 2, 3, 4, 5};
int arrLen;
char yn = ' ';
int[] arr1;
do {
arrLen = arr.length;
arr1 = new int[arrLen-1];
for (int i = 0; i < arrLen-1; i++) {
arr1[i] = arr[i];
}
arr = arr1;
System.out.println("当前数组如下:");
for (int i = 0; i < arr1.length; i++) {
System.out.print(arr1[i] + " ");
}
System.out.println();
System.out.print("是否继续缩减?(y/n):");
yn = scanner.next().charAt(0);
if (yn == 'n') {
break;
} else if (arr.length == 1) {
System.out.println("数组只剩下最后一个元素了,不能再缩减!");
break;
} else {
continue;
}
}while(true);
}
}
六、排序的介绍
排序的介绍
排序是将一群数据,依指定的顺序进行排列的过程。
排序的分类:
1、内部排序:
指将需要处理的所有数据都加载到内部存储器中进行排序。包括交换式排序法,选择式排序法和插入排序法。
2、外部排序方法
数据量过大,无法全部加载到内存中,需要借助外部存储进行排序,包括(合并排序法,直接合并排序法)。
这里只是讲解一个基本的排序方式,即:冒泡排序
到Java第二部分讲解数据结构和算法的时候讲解更加高级的排序。
冒泡排序的基本思想:
冒泡排序Bubble Sorting的基本思想式:通过对待排序序列从后往前面,从下标较大的元素开始,依次比较相邻的元素的指,如果发现逆序则交换,使值较大的元素逐渐从前移动向后,就像水底的气泡一样逐渐向上冒。
冒泡排序的具体案例:
BubbleSort.java
通过一个简单的例子讲解冒泡排序,我们将五个无序的:24,69,80,57,13使用冒泡排序法将其排序成一个从小到大的有序数列。
// 我的代码
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {24, 69, 80, 57, 13};
int temp = 0;
int arrLen = arr.length;
for (int i = 0; i < arrLen-1; i++) { // 需要交换的轮次
for (int j = 0; j < arrLen-1-i; j++) { // 每一轮需要交换多少次
if (arr[j] > arr[j+1]) { // 交换代码
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
for (int i = 0; i < arrLen; i++) { // 打印排序结果
System.out.print(arr[i] + " ");
}
}
}
总结:在我第一次看到冒泡排序算法的时候我们先画出各个需要比较的伦次
24, 69, 57, 13, 80
24, 69, 13, 57, 80
24, 13, 69, 57, 80
13, 24, 69, 57, 80
发现一共需要比较的伦次是4 = arrLen - 1
然后每一伦里面需要看比较几次,发现两两比较都是当前需要比较的长度-1次,即:
5-1 4-1 3-1 2-1 即 arrLen - i,因为i这里是01234,又因为需要j+1,为了不越界又需要减1
即:arrLen-1-i
// 老师的代码
for (int i = 0; i < arr.lengh - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if(arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("\n==第"+(i+1)+"轮==");
for(int j = 0; j < arr.length; j++) {
System.out.print(arr[j] + "\t");
}
}
老师的优化思想:
如果在某一轮没有进行交换说明已经是有序的了,这个时候可以提前终止排序算法。
关于冒泡排序算法,从外写到里面比较难以理解,如果从内到外可能会便于理解。

七、查找的介绍
介绍
在java中,我们常常使用的查找方式有两种,一种是顺序查找,一种是二分查找,二分查找,在讲解算法的时候讲解。
案例演示:
1、有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王猜数游戏:从键盘中任意输入一个名称,判断数列中是否包含此名称,【顺序查找】,要求:如果找到了,就提示找到了,并且给出下标值。
思想:
就是将查找内容和数组中的元素一个个进行比较,如果内容相等就返回结果。
2、请对一个有序数组进行二分查找{1,8,10,89,1000,1234},输入一个数看看该数组是否存在此数,并且求出下标,如果没有就提示“没有这个数".
思想:
首先这个数组应该是有序的数组,找到中间的,如果不是就看比这个数是大还是小,大就往右边找,小就往左边找,然后不断重复这样的操作。
第一题的代码,第二题先不写
// 老师的代码
int index = -1;
for (int i = 0; i < names.length; i++) {
if (findName.equals(names[i])) {
System.out.println("恭喜你找到 " + findName);
System.out.println("下标为 = " + i);
index = i;
break;
}
}
if (index == -1) {
System.out.println("sorry, 没有找到 " + findName);
}
八、二维数组
请使用二维数组输出如下图形:
0 0 0 0 0 0
0 0 1 0 0 0
0 2 0 3 0 0
0 0 0 0 0 0
int[][] arr = {
{0,0,0,0,0,0},
{0,0,1,0,0,0},
{0,2,0,3,0,0},
{0,0,0,0,0,0}
};
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();
}
九、二维数组的使用
使用方式1:动态初始化
1、语法:类型[][] 数组名 = new 类型[大小][大小];
2、比如::int a[][] = new int[2][3];

二维数组的第二种方式
使用方式二:动态初始化
1、先声明:类型 数组名[][];
2、再定义(开辟空间)数组名 = new 类型[大小][大小];
3、赋值(有默认值,比如int,为0默认值)
使用方式三:动态初始化,列数不确定的情况
int[][]arr = new int[3][];
这里相当于开辟了一个arr的空间,但是这个空间里面的数组没有任何的指向,都是null
for (int i = 0; i < arr.length; i++) {
arr[i] = new int[i+1];
分别给每个数组元素开辟空间
for (int j = 0; j < arr[i].length; j++) {
arr[i][j] = i + 1;
}
}
二维数组第四种使用方式是静态初始化
1、定义 类型 数组名[][] = {{值1,值2...},{值1,值2...},{值1,值2...}}
写的时候需要注意,不要少了花括号
int[][] arr = {{1,1,1}, {8,8,9}, {100}};
练习:
TwoDimensionalArray05.java
int arr[][] = {{4,6}, {1,4,5,7}, {-2}};
遍历该二维数组,并得到和
public class TwoDimensionalArray05 {
public static void main(String[] args) {
int[][] arr = {{4, 6}, {1, 4, 5, 7}, {-2}};
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 = " + sum);
}
}
1、使用二维数组打印一个10行的杨辉三角
YangHui.java
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
其实就是基于之前的空心金字塔,只是没有了最后一行的中间部分
靠这一点来处理外边的1,每一行的第一次和最后一次打印1
然后依靠j和i的关系处理金字塔的形状
中间部分就是当前数字等于上一行的前一列加上上一行的当前列的数字
然后根据之前讲过的列不确定的写法,在定义的时候不要写列,到需要开辟空间的时候
再使用new开辟空间,当处理行的时候就是要开辟一个新的数组了,所以写在外层for
// 我的代码
public class YangHui {
public static void main(String[] args) {
int rows = 10;
int[][] arr = new int[rows][];
//1
//1 1
//1 2 1
//1 3 3 1
//1 4 6 4 1
//第三行开始中间的数3等于上左加上1 + 2 = 3第二个三等于上左加上2 + 1 = 3
//第四行的第一个4 = 1 + 3,6 = 3 + 3,第二个4 = 3 + 1
// 第一个和最后一个输出1
for (int i = 0; i < rows; i++) { // 控制行数
arr[i] = new int[i+1];
for (int j = 0; j <= i; j++) {
if (j == 0 || j == i) {
arr[i][j] = 1;
} else {
arr[i][j] = arr[i-1][j-1] + arr[i-1][j];
}
}
}
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();
}
}
}
// 老师的分析过程:
1、第一行有一个元素,第n行有n个元素
2、每一行开始的第一个元素和最后一个元素都是1
3、从第三行开始,对非第一个元素和最后一个元素的值
arr[i][j] = arr[i-1][j] + arr[i-1][j-1];
老师的代码
int[][] yangHui = new int[10][];
for (int i = 0; i < yangHui.length; i++) {
yangHui[i] = new int[i+1];
for (int j = 0; j < yangHui[i].length; j++) {
if (j == 0 || j == yangHui[i].length - 1) {
yangHui[i][j] = 1;
} else {
yangHui[i][j] = yangHui[i-1][j] + yangHui[i-1][j-1];
}
}
}
for (int i = 0; i <yangHui.length; i++) {
for (int j = 0; j < yangHui[i].length; j++) {
System.out.print(yangHui[i][j] + "\t");
}
System.out.println();
}
十、二维数组的使用细节和注意事项
1、一维数组的声明方式有:
int[] x 或者 int x[]
2、二位数组的声明方式有:
int[][] y或者 int[] y[] 或者 int y[][]
3、二维数组实际上是由多个一维数组组成的,它各个一维数组的长度可以相同,也可以不同。比如:
map[][]是一个二维数组
map [][] = {{1,2},{3,4,5}}
由map[0]是一个含有两个元素的一维数组,map[1]是一个含有三个元素的一维数组构成,我们也称为列数不等的二维数组。
十一、练习
声明:int[] x,y[];以下选项允许通过编译的是:
这里x是一维数组,y是二维数组
x[0] = y;
因为x中只能放int,因为y是二维数组所以不能放进去。
y[0] = x;
y是二维数组,y[0]是一个一维数组,x也是一个一维数组,是可以的
y[0][0] = x;
将一个一维数组赋值给一个int,错误
x[0][0] = y;
x是一维数组,错误
y[0][0] = x[0];
两边都是int可以
x = y;
将二维数组赋值给一维数组,错误
1、下面数组定义正确的有:
A.String strs[] = {'a', 'b', 'c'};
error,将char给到String
b.String[] strs = {"a", "b", "c"};
true
C.String[] strs = new String{"a","b","c"};
error,没有这种两者结合的方式
D.String strs[] = new String[]{"a", "b", "c"};
这个是可以通过的,这个要知道
E.String[] strs = new String[3]{"a", "b", "c"};
这里是不行的,这里如果要这么写,这里面不能写上大小
2、写出结果
String foo = "blue";
boolean[] bar = new boolean[2];
if (bar[0]) {
foo = "green";
}
System.out.println(foo);
默认是false,结果为blue
3、以下Java代码的输出结果是什么?
int num = 1;
while (num < 10) {
System.out.print(num);
if (num > 5) {
break;
}
num += 2;
}
1
3
5
7
4、已知有一个升序的数组,要求插入一个元素,该数组的顺序依然是升序的,比如:
[10, 12, 45, 90],添加23之后,
数组为[10, 12, 23, 45, 90]
分析:
// 先定义原数组
int[] arr = {10, 12, 45, 90};
int insertNum = 23;
int index = -1; // index是要插入的位置
// 遍历 arr数组,如果发现insertNum <= arr[i],说明i就是要插入的位置
// 使用 index保留 index = i
// 如果遍历完毕之后,没有发现insertNum <= arr[i],说明,index = arr.length
// 即,添加到arr的最后
for (int i = 0; i < arr.length; i++) {
if (insertNum <= arr[i]) {
index = i;
break;
}
}
if (index == -1) {
index = arr.length;
}
// 扩容
// 先创建一个新的数组,大小arr.length + 1
int[] arrNew = new int[arr.length + 1];
// 拷贝到arrNew,并且跳过index位置
for (int i = 0,j = 0; i < arrNew.length; i++) {
if (i != index) {
arrNew[i] = arr[j];
j++;
} else {
arrNew[i] = insertNum;
}
}
arr = arrNew;
System.out.println("=====插入后,arr数组的元素情况=====");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
5、随机生成10个整数(1_100的范围)保存到数组,并倒顺序打印以及求平均值,求最大值和最大值的下标,并查找里面是否有8
int[] arr = new int[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random()*100) +1;
}
System.out.println("====arr的元素情况====");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.pirntln("\n====arr的元素情况倒叙=====");
for (int i = arr.length - 1; i >= 0; i--) {
System.out.print(arr[i] + "\t");
}
double sum = arr[0];
int max = arr[0];
int maxIndex = 0;
for (int i = 1; i < arr.length; i++) {
sum += arr[i];
if (max < arr[i]) {
max = arr[i];
maxIndex = i;
}
}
System.out.println("\nmax = " + max + " maxIndex = " + maxIndex);
System.out.println("\n平均值 = " + (sum / arr.length));
int findNum = 8;
int index = -1;
for (int i = 0; i < arr.length; i++) {
if (findNum == arr[i]) {
System.out.println("找到数" + findNum + " 下标 = " + i);
index = i;
break;
}
}
if (index == -1) {
System.out.println("没有找到数" + findNum);
}
tip:如果想要找到多个可以使用index的数组的方式,找到一个将下标放到这个数组下标中,扩容之后添加进去。
6、试着写出下列代码的打印结果
char[] arr1 = {'a', 'z', 'b', 'c'};
char[] arr2 = arr1;
arr1[2] = '韩';
for (int i = 0; i < arr2.length; i++) {
System.out.println(arr1[i] + "," + arr2[i]);
}
7、写出冒泡排序的代码
前面写过,略
6、内存图




浙公网安备 33010602011771号