一、数组概念
数组概念: 数组就是用于存储数据的长度固定的容器,保证多个数据的数据类型要一致。数组的定。所谓数组(array),就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,以便统一管理他们,然后用编号区分他们,这个名字称为数组名,编号称为下标或索引(index)。组成数组的各个变量称为数组的元素(element)。数组中元素的个数称为数组的长度(length)。
二、数组的分类
1、按维度分
-
一维数组:存储一组数据
-
二维数组:存储多组数据,相当于二维表,一行代表一组数据,这是这里的二维表每一行长度不要求一样。3
2、按元素类型分
-
基本数据类型的元素:存储数据值
-
引用数据类型的元素:存储对象(本质上存储对象的首地址)(这个在面向对象部分讲解)
三、数组的声明
一维数组的声明:
//推荐
元素的数据类型[] 数组名;
//不推荐
元素的数据类型 数组名[];
代码实现:
// 数组的声明
int ageArr[];
// 推荐第二种
int[] ageArr2;
-
数组的声明,就是要确定:
(1)数组的维度:在Java中数组的标点符号是[],[]表示一维,[][]表示二维
(2)数组的元素类型:即创建的数组容器可以存储什么数据类型的数据。元素的类型可以是任意的Java的数据类型。例如:int, String等
(3)数组名:就是代表某个数组的标识符,数组名其实也是变量名,按照变量的命名规范来命名。数组名是个引用数据类型的变量,因为它代表一组数据。
float[] score = {95, 56, 78, 98, 96, 45};
char[] hobby = {'a', 'b', 'c', 35};
一维数组的静态初始化
格式一:
数据类型[] 数组名 = {元素1,元素2,元素3...};//必须在一个语句中完成,不能分开两个语句写
格式二:
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...};
或
数据类型[] 数组名;
数组名 = new 数据类型[]{元素1,元素2,元素3...};
四、一维数组的使用
获取数组长度:
数组名.length
每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引(index)或下标,可以通过数组的索引/下标访问到数组中的元素。
数组名[索引/下标]
数组的下标范围:
Java中数组的下标从[0]开始,下标范围是[0, 数组的长度-1],即[0, 数组名.length-1]
五、数组的下标越界异常
当访问数组元素时,下标指定超出[0, 数组名.length-1]的范围时,就会报数组下标越界异常:ArrayIndexOutOfBoundsException。
六、一维数组的遍历
数组遍历: 就是将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基石。for循环与数组的遍历是绝配。
eg:
public class Test05ArrayIterate {
public static void main(String[] args) {
int[] arr = new int[]{1,2,3,4,5};
//打印数组的属性,输出结果是5
System.out.println("数组的长度:" + arr.length);
//遍历输出数组中的元素
System.out.println("数组的元素有:");
for(int i=0; i<arr.length; i++){
System.out.println(arr[i]);
}
}
}
七、一维数组的动态初始化
什么是动态初始化?
动态初始化就是先确定元素的个数(即数组的长度),而元素此时只是默认值,并不是真正的数据。元素真正的数据需要后续单独一个一个赋值。
一维数组的动态初始化的格式
数组存储的元素的数据类型[] 数组名 = new 数组存储的元素的数据类型[长度];
或
数组存储的数据类型[] 数组名;
数组名字 = new 数组存储的数据类型[长度];
notice:
-
new:关键字,创建数组使用的关键字。因为数组本身是引用数据类型,所以要用new创建数组对象。
-
[长度]:数组的长度,表示数组容器中可以存储多少个元素。
-
注意:数组有定长特性,长度一旦指定,不可更改。和水杯道理相同,买了一个2升的水杯,总容量就是2升是固定的。
八、数组元素的默认值
九、一维数组的内存分析
内存概述:
内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。只要计算机在运行中,CPU就会把需要运算的数据调到内存中进行运算,当运算完成后CPU再将结果传送出来。我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存。
数组下标为什么是0开始?
因为第一个元素距离数组首地址间隔0个单元格。
十、数组元素排序
排序算法概述
直接选择排序
public class Test18SelectSort{
public static void main(String[] args){
int[] arr = {6,9,2,9,1};
//直接选择排序,轮数 = 数组的元素总个数-1
/*
arr.length=5
i=0
i=1
i=2
i=3
*/
for(int i=0; i<arr.length-1; i++){
//找出本轮的最小值,及其下标
/*
i=0,第1轮,查找的范围是[0,4],一开始假设arr[0]最小
i=1,第2轮,查找的范围是[1,4],一开始假设arr[1]最小
i=2,第3轮,查找的范围是[2,4],一开始假设arr[2]最小
i=3,第4轮,查找的范围是[3,4],一开始假设arr[3]最小
int min = arr[i];
*/
int min = arr[i];
int index = i;
//用[i+1, arr.length-1]范围的元素与min比较
for(int j=i+1; j<arr.length; j++){
if(arr[j] < min){
min = arr[j];
index = j;
}
}
//判断min是否在它应该在的位置
/*
i=0,第1轮,最小值应该在arr[0]位置,它现在在arr[index]位置
i=1,第2轮,最小值应该在arr[1]位置,它现在在arr[index]位置
i=2,第3轮,最小值应该在arr[2]位置,它现在在arr[index]位置
i=3,第4轮,最小值应该在arr[3]位置,它现在在arr[index]位置
最小值应该在arr[i]位置, 如果index!=i,说明它不在应该在的位置,
就交换arr[i]和arr[index]位置
*/
if(index!=i){
int temp = arr[i];
arr[i] = arr[index];
arr[index] = temp;
}
}
//完成排序,遍历结果
for(int i=0; i<arr.length; i++){
System.out.print(arr[i]+" ");
}
}
}
冒泡排序
public class Test19BubbleSort{
public static void main(String[] args){
int[] arr = {6,9,2,9,1};
//目标:从小到大
//冒泡排序的轮数 = 元素的总个数 - 1
//轮数是多轮,每一轮比较的次数是多次,需要用到双重循环,即循环嵌套
//外循环控制 轮数,内循环控制每一轮的比较次数和过程
for(int i=1; i<arr.length; i++){ //循环次数是arr.length-1次/轮
/*
假设arr.length=5
i=1,第1轮,比较4次
arr[0]与arr[1]
arr[1]与arr[2]
arr[2]与arr[3]
arr[3]与arr[4]
arr[j]与arr[j+1],int j=0;j<4; j++
i=2,第2轮,比较3次
arr[0]与arr[1]
arr[1]与arr[2]
arr[2]与arr[3]
arr[j]与arr[j+1],int j=0;j<3; j++
i=3,第3轮,比较2次
arr[0]与arr[1]
arr[1]与arr[2]
arr[j]与arr[j+1],int j=0;j<2; j++
i=4,第4轮,比较1次
arr[0]与arr[1]
arr[j]与arr[j+1],int j=0;j<1; j++
int j=0; j<arr.length-i; j++
*/
for(int j=0; j<arr.length-i; j++){
//希望的是arr[j] < arr[j+1]
if(arr[j] > arr[j+1]){
//交换arr[j]与arr[j+1]
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
//完成排序,遍历结果
for(int i=0; i<arr.length; i++){
System.out.print(arr[i]+" ");
}
}
}
冒泡排序的优化
class Test19BubbleSort2{
public static void main(String[] args){
int[] arr = {1,3,5,7,9};
//从小到大排序
//int lun = 0;//声明lun变量,统计比较几轮
//int count = 0;//声明count变量,统计比较的次数
for(int i=1; i<arr.length; i++){
//lun++;
boolean flag = true;//假设数组已经是有序的
for(int j=0; j<arr.length-i; j++){
//count++;
//希望的是arr[j] < arr[j+1]
if(arr[j] > arr[j+1]){
//交换arr[j]与arr[j+1]
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = false;//如果元素发生了交换,那么说明数组还没有排好序
}
}
if(flag){
break;
}
}
//System.out.println("一共比较了" + lun +"轮");
//System.out.println("一共比较了" + count +"次");
//完成排序,遍历结果
for(int i=0; i<arr.length; i++){
System.out.print(arr[i]+" ");
}
}
}
数组元素的查找
顺序查找
public class Test14ArrayOrderSearch {
//查找value第一次在数组中出现的index
public static void main(String[] args){
int[] arr = {4,5,6,1,9};
int value = 1;
int index = -1;
for(int i=0; i<arr.length; i++){
if(arr[i] == value){
index = i;
break;
}
}
if(index==-1){
System.out.println(value + "不存在");
}else{
System.out.println(value + "的下标是" + index);
}
}
}
二分查找
import java.util.Scanner;
public class Test15ArrayBinarySearch {
public static void main(String[] args){
//数组一定是有序的
int[] arr = {8,15,23,35,45,56,75,85};
Scanner input = new Scanner(System.in);
System.out.print("请输入你要查找的值:");
int target = input.nextInt();
int index = -1;
for(int left = 0,right = arr.length-1; left<=right; ){
//int mid = (left+right)/2;
int mid = left + (right-left)/2;
if(arr[mid] == target){
index = mid;
break;
}else if(target > arr[mid]){
//说明target在[mid]右边
left = mid+1;
}else{
//说明target<arr[mid],target在[mid]左边
right= mid-1;
}
}
if(index!=-1){
System.out.println("找到了,下标是"+index);
}else{
System.out.println("不存在");
}
}
}