- 为什么需要有数组
- 数组定义
- 数组的使用方式
- 数组细节
- 数组的赋值机制
- 数组拷贝
- 数组反转
- 数组扩容
- 数组缩减
- 排序
- 查找
- 二维数组
- 二维数组的使用方式
- 二维数组的内存
- 本章作业
- 看一个需求:
一个养鸡场有6只鸡,他们的体重分别是3kg,5kg,1kg,3.4kg,2kg,50kg,请求这六只鸡的总体重?平均体重?
- 传统方法
public class Array01 {
public static void main(String[] args) {
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 + " 平均体重为:" + avgWeight);
}
}
- 分析:
传统方法是解决了这个问题,但是将来如果有100000只鸡呢?岂不是要定义100000个变量,那么你一整天都在定义变量,效率低下,这就导致了数组的产生。
- 使用数组解决下上面的问题
- 说明
- double[] double类型的数组,{3,5,1,3.4,2,50}表示数组的元素/值,hens 是数组名。
- 可以通过 hens[下标]访问数组元素。
- 数组的下标从0开始,hens[0]是第一个元素,hens[1]是第二个元素。
- 数组元素的个数称为数组的大小/长度,java中数组名.length是数组的大小。
public class Array02 {
public static void main(String[] args) {
double[] hens = {3, 5, 1, 3.4, 2, 50};
double totalWeight = 0;
for(int i = 0; i < hens.length; i++) {
totalWeight += hens[i];
}
System.out.println("总体重=" + totalWeight + "平均体重=" + (totalWeight / 6));
}
}
数组定义
数组的使用方式
- 数(数据)组(一组),一组相同类型的数据。
- 是数据类型,是引用类型。
- 1.动态初始化
数据类型[] 数组名 = new 数据类型[数组大小];
或者 数据类型 数组名[] = new 数据类型[数组大小];
- 数组的引用 数组名[下标/索引],例如a[2]访问的是数组的第三个元素
- 案例:
- 循环的输入5个成绩,保存到数组,并输出。
import java.util.Scanner;
public class Array03 {
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
double[] scores = new double[5];
//遍历输入
for(int i = 0; i < a.length; i++) {
System.out.println("请输入" + (i + 1) + "个元素的值");
scores[i] = myScanner.nextDouble();
}
//遍历输出
for(int i = 0; i < a.length; i++) {
System.out.println("第" + (i + 1) + "个元素的值");
}
}
}
- 2.动态初始化
- 1.先声明数组:
数据类型[] 数组名; 或 数据类型 数组名[];。
这样并没有为数组分配空间,数组名 = null(空);
例如 int[] a; 此时 a = null- 2.再创建数组:
数组名 = new 数据类型[数组大小];
真正的为数组分配空间
- 前面的案例采用上面的方式
import java.util.Scanner;
public class Array03 {
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
double[] scores;
scores = new double[5];
//遍历输入
for(int i = 0; i < a.length; i++) {
System.out.println("请输入" + (i + 1) + "个元素的值");
scores[i] = myScanner.nextDouble();
}
//遍历输出
for(int i = 0; i < a.length; i++) {
System.out.println("第" + (i + 1) + "个元素的值");
}
}
}
- 静态初始化
数组细节
- 数据类型[] 数组名 = {元素值1,元素值2,…}
- 适用 :知道数组有多少元素,且知道具体值
- 例如: int[] a = {1, 2, 3, 4};
1.数组中元素类型必须和定义的数组的类型一致或兼容
2.数组中的元素既可以为基本类型,又可以为引用类型。
3.数组创建后,没有赋值有默认值
char u0000,byte 0, short 0,int 0, long 0, float 0.0, double 0.0, boolean fasle,String null.
4.使用数组步骤:
- 1.声明数组并开辟空间
- 2.给元素赋值
- 3.使用数组
5.数组是引用类型,数组是对象
6.数组的最小下标为0,最大为长度 - 1
- 数组练习
1.创建char类型数组26个元素的数组,分别放置’A’~ ‘Z’,使用for循环所有元素并打印出来
public class ArrayExercise01 {
public static void main(String[] args) {
char[] c = new int[26];
for(int i = 0; i < c.length; i++) {
//注意,必须有强制转换
//否则 报错 char -> int
c[i] = (int)('A' + i);
}
//遍历输出
for(int i = 0; i < c.length; i++) {
System.out.print(c[i] + " ");
}
}
}
2.求出一个数组int[]的最大值{4, -1, 9, 10, 23}, 并得到对应的下标
public class ArrayExercise02 {
public static void main(String[] args) {
int[] a = {4, -1, 9, 10, 23};
//假设法,假设第一个元素为最大值
int max = a[0];
//保存最大元素的下标
int maxValueIndex = 0;
for(int i = 1; i < a.length; i++) {
//判断
if(a[i] > max) {
max = i;
maxValueIndex = i;
}
}
System.out.println("最大值为:" + max + "对应的下标为:"+ maxValueIndex);
}
}
3.求出一个数组的和和平均值
public class ArrayExercise03 {
public static void main(String[] args) {
int[] a = {1, 2, 42, 12, 3241, 313};
//定义变量
int sum = 0;
//定义平均值
int avg = 0;
for(int i = 0; i < a.length; i++) {
sum += a[i];
}
avg = sum / a.length;
//输出
System.out.println("数组的和为:" + sum + "平均值为" + avg);
}
}
数组的赋值机制
1.基本数据类型赋值:赋的值就是具体的值,赋值方式为值拷贝,彼此不会相互影响
2.数组赋值:赋的值是一个地址,赋值方式为引用赋值,会相互影响。
public class ArrayAssign {
public static void main(String[] args) {
//1.基本数据类型赋值
int n1 = 23;
int n2 = n1;
n2 = 32;
System.out.println("n1=" + n1);
System.out.println("n2=" + n1);
//2.数组赋值
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1;
arr2[0] = 12;
System.out.println("=====arr1的元素如下====");
for(int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
}
}
- 基本数据类型和数组类型赋值原理
定义:创建新数组,和原来数组的内存空间是独立的,数组内容和原来数组一样。
public class ArrayCopy {
public static void main(String[] args) {
int[] arr1 = {10, 20, 30};
//创建新的数组,开辟新的数据空间
int[] arr2 = new int[arr1.length];
//遍历arr1,依次赋值到arr2
for(int i = 0; i < arr2.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{1,2,3} =》arr{3,2,1}
- 方法1(找规律)
public class ArrayReverse {
public static void main(String[] args) {
int[] arr = {11, 22, 33, 44, 55, 66};
int len = arr.length;
//思路:
//arr[0]和arr[5]交换后 {66, 22, 33, 44, 55, 11}
//arr[1]和arr[4]交换后 {66, 55, 33, 44, 22, 11}
//arr[2]和arr[3]交换后 {66, 55, 44, 33, 22, 11}
//交换3次 arr.length / 2
//每次交换 交换元素arr[i] 和 arr[arr.length - 1 - i]
for(int i = 0; i < len / 2; i++) {
int 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] + " ");
}
}
}
- 方法2(开新空间,逆序赋值)
public class ArrayReverse {
public static void main(String[] args) {
int[] arr = {11, 22, 33, 44, 55, 66};
//开辟新空间
int[] arr1 = new int[arr.length];
//逆序遍历 arr,并赋值给arr1
//arr[5] -> arr1[0]
//arr[4] -> arr1[1]
//arr[3] -> arr1[3]
//即 arr[arr.length - 1 - i] -> arr1[i]
for(int i = arr.length - 1, j = 0; i >= 0; i--, j++) {
arr1[j] = arr[i];
}
//让arr 指向 arr1的堆空间
arr = arr1;
System.out.println("反转后的数组元素:");
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i] + " ");
}
}
}
数组扩容
- 1,2
import java.util.Scanner;
public class ArrayAdd {
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
int[] arr = {1, 2 , 3};
//定义新数组
int[] arr1 = new int[arr.length + 1];
//遍历arr
for(int i = 0; i < arr.length; i++) {
arr1[i] = arr[i];
}
//把添加的元素赋值给 arr1的最后元素
arr1[arr1.length - 1] = 3;
//让arr指向arr1
arr = arr1;
System.out.println("arr扩容后的元素");
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i] + " ");
}
}
}
- 1,2, 3
import java.util.Scanner;
public class ArrayAdd02 {
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
int[] arr = {1, 2 , 3};
do{
//定义新数组
int[] arr1 = new int[arr.length + 1];
//遍历arr
for(int i = 0; i < arr.length; i++) {
arr1[i] = arr[i];
}
int addNum = myScanner.nextInt();
//把添加的元素赋值给 arr1的最后元素
arr1[arr1.length - 1] = addNum;
//让arr指向arr1
arr = arr1;
System.out.println("arr扩容后的元素");
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i] + " ");
}
//询问是否继续添加
System.out.println("是否继续添加y/n");
char reply = myScanner.next().charAt(0);
}while(reply == 'n');
}
}
数组缩减
import java.util.Scanner;
public class ArrayReduce {
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
int[] arr = {1, 2, 3, 4, 5};
while(true) {
int arr1 = mew int[arr.length - 1];
//遍历原来的数组
for(int i = 0 ; i < arr.length; i++) {
arr1[i] = arr[i];
}
//询问是否继续缩减
System.out.println("是否继续缩减?");
reply = myScanner.next().charAt(0);
//如果不缩减 直接退出
if(reply == 'n') {
break;
} else {
//回答 是 y
//如果只剩下一个元素 直接退出
if(arr.length == 1) {
System.out.println("只剩下最后一个元素,不能再缩减");
break;
} //否则继续缩减
}
}
//arr指向 arr1的堆空间
arr = arr1;
}
}
排序
定义:将一组数据,按照指定顺序进行排列
分类:
内部排序:把数据都装入内存,进行排序
外部排序:数据量太大,无法全部装入内存,需要借助外部存储进行排序
- 冒泡排排序(Bubble Sort)
思想:依次比较相邻元素,若和指定顺序不一致则交换,向后移动,重复上述动作,第一轮排序最后一个元素为最大值或最小值,经过若干轮(数据量 - 1),排序完成。
- 原理图
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {24, 69, 80, 57, 13};
int temp = 0;
for(int i = 0; i < arr.length - 1; i++) {
for(int j = 0; j < arr.length - 1 - i; i++) {
if(arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
System.out.println("====第+(i + 1)+轮===");
for(int j = 0; j < arr.length; i++) {
System.out.println(arr[j] + "t");
}
}
}
}
查找
定义:就是在数列,查找存不存在一个数。
- 顺序查找
import java.util.Scanner;
public class SeqSearch {
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
String[] names = {"白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"};
System.out.println("请输入一个名称:");
String findName = myScanner.next();
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
public class TwoDimensionalArray {
public static void main(String[] args) {
//形式上 int [][]
//二维数组是每个元素都是一维数组的二维数组
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; i++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
二维数组的使用方式
- 1.动态初始化
类型[][] 数组名 = new 类型[大小][大小];
- 2.动态初始化
- 先声明:
类型[][] 数组名;- 再创建数组
数组名 = new 类型[大小][大小];
- 3.动态初始化- 列数不确定
定义:每个二维数组的一维数组元素的元素个数不一样
输出如下形式
1
2 2
3 3 3
public class TwoDimensionalArray {
public static void main(String[] args) {
//创建了一个二维数组
//但每一个一维数组没有开辟空间
int[][] arr = new int[3][];
for(int i = 0; i < arr.length; i++) {
arr[i] = new int[i + 1];
//给每一个一维数组赋值
for(int j = 0; j < arr[i].length; i++) {
arr[i][j] = i + 1;
}
}
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();
}
}
}
- 4.静态初始化
二维数组的内存
- 类型[][] 数组名 = {{值1,值2,…}, {值1,值2,…}, {值1,值2,…}, {值1,值2,…},…};
- 例如 int[][] arr = {{1, 2}, {1,2, 3}, …};
- 每个一维数组的元素个数可以不同
- 练习
1.int[][] = {{4, 6}, {1,4, 5, 7}, {-2}};遍历二维数组,求和
public class TwoDimensionalArrayExercise01 {
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);
}
}
2.打印10行的杨辉三角
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 5 1
public class YangHui {
public static void main(String[] args) {
int[][] arr = new int[10];
//给每个一维数组开空间
for(int i = 0; i < arr.length; i++) {
arr[i] = new int[i + 1];
}
//给每一个数组赋值
for(int j = 0; j < arr[i].length; j++) {
//每行的第一个和最后一个元素为1
if(j == 0 || j == arr[i].length - 1) {
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] + "t");
}
System.out.println();
}
}
}
- 二维数组细节
- 二维数组还有一种声明形式:
数据类型[] 数组名[];
- 练习
1.
2.求结果
public class HomeWork02 {
public static void main(String[] args) {
String foo = "blue";
boolean[] bar = new boolean[2];
if(bar[0]) {
foo = "green";
}
System.out.println(foo);
}
}
3.求结果
public class HomeWork03 {
public static void main(String[] args) {
int num = 1;
while(num < 10) {
System.out.println(num);
if(num > 5) {
break;
}
num += 2;
}
}
}
4.已知有一个升序的数组,要求插入一个元素,该元素依然是升序,比如:
[10, 12, 45, 90], 添加23后,数组为 [10, 12, 23, 45, 90]
public class HomeWork04 {
public static void main(String[] args) {
int[] arr = {10, 12, 45, 90};
int insertValue = 23;
//先找到插入元素在数组中应在的位置
int position = -1;
for(int i = 0; i < arr.length ; i++) {
if(max <= arr[i]) {
position = i;
break;
}
}
//如果不在原来数组的任何一个位置 则在末尾
if(position == -1) {
position = arr.length ;
}
//创建新数组
int[] arrNew = new int[arr.length + 1];
// 赋值, 双指针
for(int i = 0, j = 0 ; i < arrNew.length; i++) {
if(i != position) {//将旧数组元素赋值过来
arrNew[i] = arr[j];
j++;
} else {//这个位置就是添加元素的位置
arrNew[i] = insertValue;
}
}
//arr指向arrNew;
arr = arrNew;
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i] + " ");
}
}
}
5.随机生成10个整数(1~100),保存到数组,倒数打印,求平均值、求最大值和最大值下标,并查找里面是否有8
public class HomeWork05 {
public static void main(String[] args) {
int[] arr = new int[10];
//赋值
for(int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random() * 100 + 1);
}
//倒序打印
for(int i = arr.length - 1; i >= 0; i--) {
System.out.println(arr[i] + " ");
}
//求平均值
double sum = arr[0];
double avg = 0;
double max = arr[0];
double 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("avg=" + avg);
System.out.println("max=" + max + "maxIndex=" + maxIndex);
//记录是否有8
int findNum = 8;
int index = -1;
for(int i = 0; i < arr.length; i++) {
if(findNum == arr[i]) {
index = i;
break;
}
}
if(index != -1) {
System.out.println("找到" + findNum +"下标为" + index);
} else {
System.out.println("没有找到" + findNum);
}
}
}
6.求结果
public class HomeWork06 {
public static void main(String[] args) {
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.冒泡排序代码
public class HomeWork07 {
public static void main(String[] args) {
int[] arr = {20, 2332, 12, -12, 1312,31};
int temp = 0;
for(int i = 0; i < arr.length - 1; i++) {//排序的轮数
for(int j = 0; j < arr.length - 1 - i; j++) {//每一轮排序的次数
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
System.out.println("===排序后==");
for(int i = 0; i < arr.length - 1; i++) {
System.out.println(arr[i] + "t");
}
}
}



