目录
数组
为什么需要数组
数组介绍
数组快速入门
数组的使用
使用方式1-动态初始化
数组的定义
数组的引用(使用/访问/获取数组元素)
快速入门案例
使用方式2-动态初始化
先声明数组
创建数组
使用方式3-静态初始化
初始化数组
快速入门案例【养鸡场】
数组使用注意事项和细节
数组应用案例
数组赋值机制
数组拷贝
数组反转
数组添加
练习题
排序
介绍
1、内部排序
2、外部排序法
冒泡排序法
冒泡排序法案例
总结冒泡排序特点
查找
查找介绍
案例演示:
多维数组-二维数组
二维数组的应用场景
快速入门
二维数组的使用
使用方式1:动态初始化
使用方式2:动态初始化
使用方式3:动态初始化-列数不确定
使用方式4:静态初始化
二维数组练习题
二维数组的应用案例
二维数组使用细节和注意事项
二维数组练习题
一个养鸡场有6只鸡,它们的体重分别是3kg,5kg,1kg,3.4kg,2kg,50kg。请问这六只鸡的总体重是多少?平均体重是多少?请你编一个程序。
public class Array01 {
//编写一个main方法
public static void main(String[] args) {
// 一个养鸡场有6只鸡,它们的体重分别是3kg,5kg,1kg,3.4kg,2kg,50kg。
// 请问这六只鸡的总体重是多少?平均体重是多少?请你编一个程序。
// 思路分析
// 1.定义六个变量 double ,求和得到总体重
// 2.平均体重=总体重/6
// 3.分析传统实现的方式问题。6->600->566
// 4.引进新的技术 -> 数组来解决。
double hen1 = 3;
double hen2 = 5;
double hen3 = 1;
double hen4 = 3.4;
double hen5 = 2;
double hen6 = 50;
double totalweight = hen1 + hen2 + hen3 + hen4 + hen5 + hen6;
double avgWeight = totalweight / 6;
System.out.println("总体重=" + totalweight);
}
}
数组可以存放多个同一类型的数据。数组也是一种数据类型,是引用类型。
即:数(数据)组(一组)就是一组数据
public class Array01 {
//编写一个main方法
public static void main(String[] args) {
// 一个养鸡场有6只鸡,它们的体重分别是3kg,5kg,1kg,3.4kg,2kg,50kg。
// 请问这六只鸡的总体重是多少?平均体重是多少?请你编一个程序。
// 思路分析
// 1.定义六个变量 double ,求和得到总体重
// 2.平均体重=总体重/6
// 3.分析传统实现的方式问题。6->600->566
// 4.引进新的技术 -> 数组来解决。
// 定义一个数组
// 解读
// 1.double[]表示是double类型的数组,数组名 hens
// 2.{3,5,1,3.4,2,50}表示数组的值/元素,
// 依次表示数组的第几个元素
double[] hens = {3, 5, 1, 3.4, 2, 50};
// 便利数组得到的所有元素的和,使用for
// 解读
// 1.我们可以通过hens[下标]来访问数组的元素
// 下标是从开始编号的比如第一个元素就是 hens[0]
// 第2个元素就是 hens[1],依次类推
// 2.通过for就可以循环的访问数组的元素/值
// 3.使用一个变量totalweight将各个元素累积
// 可以通过 数组名 .length 得到数组的大小/长度
double totallWeight = 0;
for (int i = 0; i < hens.length; i++) {
totallWeight += hens[i];
}
System.out.println("总体重=" + totallWeight + "平均体重=" + (totallWeight / 6));
}
}
运行结果
数据类型数组名[ ]=new数据类型[大小]
int a[ ]=new int[5];//创建了一个数组,名字a,存放5个int
数组名[下标/索引]比如:你要使用a数组的第3个数a[2]
数组的下标从0开始
循环输入5个成绩,保存到double数组,并输出
import java.util.Scanner;
public class Array02 {
//编写一个main方法
public static void main(String[] args) {
// 循环输入5个成绩,保存到double数组,并输出
// 数据类型数组名[ ]=new数据类型[大小]
//1.创建一个double数组,大小5
double scores[] = new double[5];
//2.循环输入
// score.length 表示数组的大小/长度
Scanner myScanner = new Scanner(System.in);
for (int i = 0; i < scores.length; i++) {
System.out.println("请输入第" + i + "个元素的值");
scores[i] = myScanner.nextDouble();
}
//输出,遍历数组
System.out.println("==数组的元素/值的情况如下==");
for (int i = 0; i < scores.length; i++) {
System.out.println("第" + (i + 1) + "个元素的值=" + scores[i]);
}
}
}
运行结果
语法:数据类型 数组名[];也可以 数据类型[] 数组名;
int a[];或者int[] a;
语法:数组名=new 数据类型[大小];a=new int[10];
案例演示【前面修改即可】
import java.util.Scanner;
public class Array02 {
//编写一个main方法
public static void main(String[] args) {
// 循环输入5个成绩,保存到double数组,并输出
// 数据类型数组名[ ]=new数据类型[大小]
//1.创建一个double数组,大小5
// (1)第1种动态分配方式
// double scores[] = new double[5];
// (2)第2种动态分配方式,先声明数组,在new 分配空间
double scores[];//声名数组,这时scores是null
scores = new double[5];//分配内存空间,可以存放数据
//2.循环输入
// score.length 表示数组的大小/长度
Scanner myScanner = new Scanner(System.in);
for (int i = 0; i < scores.length; i++) {
System.out.println("请输入第" + i + "个元素的值");
scores[i] = myScanner.nextDouble();
}
//输出,遍历数组
System.out.println("==数组的元素/值的情况如下==");
for (int i = 0; i < scores.length; i++) {
System.out.println("第" + (i + 1) + "个元素的值=" + scores[i]);
}
}
}
语法:数据类型数组名0={元素值元素值...}
int a[ ]={2,5,6,7,8,89,90,34.56},如果知道数组有多少元素,具体值上面的用法相当于:
int a[ ]=new int[9];
a[0]=2;a[1]=5;a[2]=6; a[3]=7;a[4]=8;a[5]=89;a[6]=90;a[7]=34;a[8]=56;
案例Array01.java 讲过
double hens[ ]= {3,5,1,3,4,2,50};等价
double hens[ ]= new double[6];
hens[0]= 3; hens[1] = 5; hens[2] = 1; hens[3] = 3.4; hens[4]=2; hens[5]=50;
1、数组是多个相同类型数据的组合,实现对这些数据的统一管理
2、数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用。
3、数组创建后如果没有赋值有默认值int0,short 0,byte 0,long 0,float 0.0,double 0.0,char \u0000,boolean false,String null
4、使用数组的步骤1.声明数组并开辟空间2 给数组各个元素赋值3 使用数组
5、数组的下标是从0开始的。
6、数组下标必须在指定范围内使用,否则报:下标越界异常,比如
int [] arr= new int[5];则有效下标为0-4
7、数组属引用类型,数组型数据是对象(object)
public class ArrayDetial {
//编写一个main方法
public static void main(String[] args) {
// 1、数组是多个相同类型数据的组合,实现对这些数据的统一管理
// int[] arr1 = {1, 2, 3, 60, "hello"};//String -> int
double[] arr2 = {1.1, 2.2, 3.3, 60.6, 100};//int -> double
// 2、数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用。
String[] arr3 = {"北京", "jack", "milan"};
// 3、数组创建后如果没有赋值有默认值
// int0,short 0,byte 0,long 0,
// float 0.0,double 0.0,char \u0000,
// boolean false,String null
short[] arr4 = new short[3];
System.out.println("====数组arr4====");
for (int i = 0; i < arr4.length; i++) {
System.out.println(arr4[i]);
}
// 6、数组下标必须在指定范围内使用,否则报:下标越界异常,比如
// int [] arr= new int[5];则有效下标为0-4
// 即数组的下标/索引 最小0 最大 数组长度-1 (4)
int[] arr=new int[5];
// System.out.println(arr[5]);//数组越界
}
}
1、创建一个char类型的26个元素的数组,分别放置'A'-'Z'。使用for循环访问
所有元素并打印出来。提示:char类型数据运算'A'+1 ->'B'
public class ArrayExercise {
//编写一个main方法
public static void main(String[] args) {
// 1、创建一个char类型的26个元素的数组,分别放置'A'-'Z'。
// 使用for循环访问 所有元素并打印出来。
// 提示:char类型数据运算'A'+1 ->'B'
char[] chars = new char[26];
for (int i = 0; i < chars.length; i++) {
//chars 是 char[]
//chars[i] 是char
chars[i] = (char) ('A' + i);//'A' + i 是int,需要强制转换
}
System.out.println("====chars数组====");
for (int i = 0; i < chars.length; i++) {
System.out.print(chars[i] + " ");
}
}
}
运行结果
2、请求出一个数组int[]的最大值{4,-1,9,10,23},并得到对应的下标。
public class ArrayExercise {
//编写一个main方法
public static void main(String[] args) {
// 2、请求出一个数组int[]的最大值{4,-1,9,10,23},并得到对应的下标。
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、数组在默认情况下是引用传递,赋的值是地址。
看一个案例,并分析数组赋值的内存图(重点)。
public class ArrayAssign {
//编写一个main方法
public static void main(String[] args) {
//基本数据类型赋值,赋值方式为值拷贝
//n2的变化不会影响n1的值
int n1 = 10;
int n2 = n1;
n2 = 80;
System.out.println("n1=" + n1);//10
System.out.println("n2=" + n2);//80
//数组在默认情况下是引用传递,赋的值是地址,赋值方式为引用赋值
//是一个地址,arr2变化会影响到arr1
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1;//把arr1赋值给arr2
arr2[0] = 10;
//看看arr1的值
System.out.println("=====arr1的元素=====");
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
}
}
运行结果
编写代码实现数组拷贝(内容复制)
将int[] arr1 = {10,20,30};拷贝到arr2数组
public class ArrayCopy {
//编写一个main方法
public static void main(String[] args) {
// 将int[] arr1 = {10,20,30};拷贝到arr2数组
int[] arr1 = {10, 20, 30};
int[] arr2 = new int[arr1.length];
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]);
}
}
}
运行结果
要求:把数组的元素内容反转。
arr {11,22,33,44,55,66] →{66,55,44,33,22,11}
1、方式1:通过找规律反转
public class ArrayReverse {
//编写一个main方法
public static void main(String[] args) {
//定义数组
int[] arr = {11, 22, 33, 44, 55, 66};
int temp;
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.println(arr[i] + "\t");
}
}
}
运行结果
2、方式2:使用逆序赋值方式
public class ArrayReverse {
//编写一个main方法
public static void main(String[] args) {
//定义数组
int[] arr = {11, 22, 33, 44, 55, 66};
int[] arr2 = new int[arr.length];
for (int i = arr.length - 1, j = 0; i >= 0; i--, j++) {
arr2[j] = arr[i];
}
arr = arr2;//让arr指向arr2数据空间,此时arr原来的数据空间没有被变量引用会被当作垃圾,销毁
System.out.println("====翻转后数组====");
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i] + "\t");
}
}
}
运行结果
要求:实现动态的给数组添加元素效果,实现对数组扩容。
1、原始数组使用静态分配
int[ ] arr = {1,2,3]
2、增加的元素4,直接放在数组的最后arr = {1,2,3,4}
3、用户可以通过如下方法来决定是否继续添加,添加成功,是否继续? y/n
import java.util.Scanner;
public class ArrayAdd {
//编写一个main方法
public static void main(String[] args) {
// 1、原始数组使用静态分配
// int[ ] arr = {1,2,3]
// 2、增加的元素4,直接放在数组的最后arr = {1,2,3,4}
// 3、用户可以通过如下方法来决定是否继续添加,添加成功,是否继续? y/n
Scanner myScanner = new Scanner(System.in);
// 初始化数组
int[] arr = {1, 2, 3};
do {
int[] arrNew = new int[arr.length + 1];
// 遍历 arr 数组,以此将arr的元素拷贝到arrNew数组
for (int i = 0; i < arr.length; i++) {
arrNew[i] = arr[i];
}
System.out.println("请输入你要添加的元素");
int addNum = myScanner.nextInt();
// 把addNum赋值给arrNew最后一个元素
arrNew[arrNew.length - 1] = addNum;
// 让arr指向arrNew
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);
}
}
运行结果
有一个数组{1,2,3,4,5},可以将该数组进行缩减,提示用户是否继续缩减,每次缩减最后那个元素。当只剩下最后一个元素,提示,不能再缩减。
import java.util.Scanner;
public class ArrayDecrease {
//编写一个main方法
public static void main(String[] args) {
// 有一个数组{1,2,3,4,5},可以将该数组进行缩减,
// 提示用户是否继续缩减,每次缩减最后那个元素。
// 当只剩下最后一个元素,提示,不能再缩减。
Scanner myScanner = new Scanner(System.in);
// 初始化数组
int[] arr = {1, 2, 3, 4, 5};
do {
int[] arrNew = new int[arr.length - 1];
// 遍历 arr 数组,以此将arr的元素拷贝到arrNew数组
for (int i = 0; i < arr.length - 1; i++) {
arrNew[i] = arr[i];
}
// 让arr指向arrNew
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;
} else if (arr.length == 1) {
System.out.println("不能再缩减");
}
} while (true);
}
}
运行结果
排序是将一群数据,依指定的顺序进行排列的过程。排序的分类:
指将需要处理的所有数据都加载到内部存储器中进行排序。
包括(交换式排序法、选择式排序法和插入式排序法);
数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。
包括(合并排序法和直接合并排序法)。
冒泡排序(Bubble Sorting)的基本思想是通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。
将五个无序:24,69,80,57,13使用冒泡排序法将其排成一个从小到大的有序数列。
1、一共有5个元素
2、一共进行了4轮排序,可以看成是外层循环
3、每1轮排序可以确定一个数的位置,比如第1轮排序确定最大数,第2轮排序,确定第2大的数位置,依次类推
4、当进行比较时,如果前面的数大于后面的数,就交换
5、每轮比较在减少4->3->2->1
分析思路->代码
public class BubbleSort {
//编写一个main方法
public static void main(String[] args) {
int[] arr = {24, 69, 80, 57, 13, 100, 121};
int temp = 0;//用于辅助交换变量
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {//4次比较
//如果前面的数>后面的数,就交换
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
System.out.println();
System.out.println("======第" + (i + 1) + "轮======");
for (int j = 0; j < arr.length; j++) {
System.out.print(arr[j] + "\t");
}
}
}
}
运行结果
在java中,我们常用的查找有两种:
1、顺序查找
2、二分查找【二分法】
1、有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王
猜数游戏:从键盘中任意输入一个名称,判断数列中是否包含此名称【顺序查找】
要求:如果找到了,就提示找到,并给出下标值。
import java.util.Scanner;
public class SeqSearch {
//编写一个main方法
public static void main(String[] args) {
// 1、有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王
// 猜数游戏:从键盘中任意输入一个名称,判断数列中是否包含此名称【顺序查找】
// 要求:如果找到了,就提示找到,并给出下标值。
//定义一个字符串数组
String[] names = {"白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"};
Scanner myScanner = new Scanner(System.in);
System.out.println("请输入名字");
String findName = myScanner.next();
//遍历数组,逐一比较,若果有,则提示信息,并退出
int index = -1;
for (int i = 0; i < names.length; i++) {
//比较 字符串比较equals,如果要找到名字就是当前元素
if (findName.equals(names[i])) {
System.out.println("恭喜你找到" + findName);
System.out.println("下标为" + i);
//把i保存到index
index = i;
break;//退出
}
}
if (index == -1) {//没有找到
System.out.println("没有找到" + findName);
}
}
}
运行结果
2、请对一个有序数组进行二分查找 {1,8,10,89,1000,1234},输入一个数看看该数组是否存在此数,并且求出下标,如果没有就提示"没有这个数"。
多维数组只介绍二维数组。
比如我们开发一个五子棋游戏,棋盘就是需要二维数组来表示。如图:
案例
请用二维数组输出如下图形
000000
001000
020300
000000
public class TwoDimensionalArray {
//编写一个main方法
public static void main(String[] args) {
// 请用二维数组输出如下图形
// 000000
// 001000
// 020300
// 000000
//解读
//1.从定义上看 int[][]
//2.可以这样理解,原来的一维数组的每个元素是一维数组,构成二维数组
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}};
//(1)
System.out.println("二维数组的元素个数=" + arr.length);
//(2)二维数组的每个元素是一维数组,所以如果需要得到每个一维数组的值 还需要再次遍历
//(3)如果要访问第(i+1)个一维数组的第(j+1)个值 arr[i][j];
// 举例 访问 3 -> 他是第3个一维数组的第4个值 arr[2][3];
System.out.println("第3个一维数组的第4个值=" + arr[2][3]);
//输出二维图形
for (int i = 0; i < arr.length; i++) {//遍历二维数组的每个元素
//
//1. arr[i] 表示 二维数组的第i+1个元素 比如arr[0]:二维数组的第一个元素
//2. arr[i].length 得到 对应的 每个一维数组的长度
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + "\t");//输出了一维数组
}
System.out.println();//换行
}
}
}
运行结果
1、语法:类型[ ][ ]数组名 = new类型[大小][大小]
2、比如:int a[ ][ ] = new int[2][3]
3、使用演示
4、二维数组在内存的存在形式
public class TwoDimensionalArray {
//编写一个main方法
public static void main(String[] args) {
int arr[][] = new int[2][3];
arr[1][1] = 8;
// 遍历arr数组
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、先声明:类型[ ][ ]数组名;
2、再定义(开辟空间)数组名=new类型[大小][大小]
3、赋值(有默认值,比如int 类型的就是0)
4、使用演示
// int arr[][] = new int[2][3];
int arr[][];//声明二维数组
arr = new int[2][3];//再开空间
1、看一个需求:动态创建下面二维数组,并输出。
public class TwoDimensionalArray {
//编写一个main方法
public static void main(String[] args) {
int[][] arr = new int[5][];//创建二维数组,但是只是确定一维数组的个数
for (int i = 0; i < arr.length; i++) {//遍历arr每个一维数组
//给每一个一维数组开空间new
//如果没有给一维数组new,那么arr[i]就是null
arr[i] = new int[i + 1];
//遍历一维数组,并且给数组的每个元素赋值
for (int j = 0; j < arr[i].length; j++) {
arr[i][j] = i + 1;
}
}
System.out.println("====arry元素====");
//遍历arr
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + "\t");
}
System.out.println();
}
}
}
运行结果
1、定义类型数组名[ ][ ]={f值1,值2.}.{值1,值2..}.{值1,值2..}}
2、使用即可[固定方式访问]
比如:
int[][]arr = {{1, 1, 1},{8, 8, 9},{100}};
解读
1、定义了一个二维数组arr
2、arr有三个元素(每个元素都是一维数组)
3、第一个一维数组有3个元素,第二个一维数组有3个元素,第三个一维数组有1个元素
int[][] arr={{4,6},{1,4,5,7},{-2}};遍历该二维数组,并得到和
public class TwoDimensionalArray {
//编写一个main方法
public static void main(String[] args) {
// int[][] arr={{4,6},{1,4,5,7,{-2}};遍历该二维数组,并得到和
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行杨辉三角
public class YangHui {
//编写一个main方法
public static void main(String[] args) {
// 规律
// 1.第一行有1个元素,第n行有n个元素2。每一行的第一个元素和最后一个元素都是1
// 3.从第三行开始,对于非第一个元秦和最后一个元素的元素的值.arr[i][j]
// 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[ ];
以下选项允许通过编译的是(b,e):