数组
数组:数组是存储同一种数据类型数据的集合容器。
数组的定义格式:
数据类型[] 变量名 = new 数据类型[长度];
例如: int【】 arr = new int[10];
定义一个变量arr指向一个存储类型为int型,长度为10的数组对象
数组的特点:
1. 数组只能存储同一种 数据类型的数据。
2. 数组是会给存储到数组中 的元素分配一个索引值的,索引值从0开始,最大的索引值是length-1;
3. 数组一旦初始化,长度固定。
4. 数组中的元素与元素之间的内存地址是连续的。
数组的内存分析:
栈内存中存放局部变量,使用new关键字初始化的对象会存在堆里面。
例如: int【】 arr = new int[10];
arr变量存放在栈中(记录数组对象的地址),并指向在堆中开辟的长度为10的数组。
注意:
局部变量: 如果一个变量是在一个方法(函数)的内部声明的,那么该变量就是一个局部变量。
成员变量: 成员变量就是定义在方法之外,类之内的.
数组操作中经常遇到的问题:
1. NullPointerException 空指针异常
原因: 引用类型变量没有指向任何对象,而访问了对象的属性或者是调用了对象的方法。
code:
int[] arr = new int[2];
arr = null ; //null 让该变量不要引用任何的对象。 不要记录任何 的内存地址。
arr[1] = 10; //空指针异常
2. ArrayIndexOutOfBoundsException 索引值越界。
原因:访问了不存在的索引值。
code:
int[] arr = new int[4];
arr[0] = 10;
arr[1] = 30;
arr[2] =40;
arr[3] = 50; //数组越界
数组的初始化方式:
动态初始化:
数据类型[] 变量名 = new 数据类型[长度];
code:
int[] arr = new int[10];
静态初始化:
数据类型[] 变量名 = {元素1,元素2.....};
code:
int[] arr = {10,20,30,40,50};
注意:如果程序一开始你就已经确定了数据,那么这时候建议使用静态初始化。如果
数据一开始还不太明确,这时候就建议使用动态初始化。
数组的常用操作:
1、查找最大值
需求: 定义一个函数接收一个int类型的数组对象,找出数组对象中 的最大元素返回给调用者。
思想:遍历数组找最大值,适用于所有类型的数组
code:
//获取数组中的最大值
public static int getMax(int[] arr){
int max = arr[0];
for (int i = 1; i<arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
}
return max;
}
2、选择排序法
需求:定义一个函数接收一个int类型的数组对象, 实现升序排序。
思想:从第一个数组数据开始,依次和所有后面的数据比较,如果数据大于要比较的数据,就交换位置。直到遍历完整个数组。
code:
//选择排序
public static int[] selectedOrder(int[] arr){
for (int i = 0; i<arr.length - 1; i++) {
for (int j = i+1; j< arr.length; j++) {
if (arr[i] > arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
3、冒泡排序法
需求:定义一个函数接收一个int类型的数组对象, 实现升序排序。
思想:每次都从index为0的元素开始比较,递进进行相邻的的比较,如果不能该数据大于要比较的数据,就交换位置。知道遍历完整个数据。
code:
//冒泡排序
public static int[] bubblingOrder(int[] arr){
for (int i = 0; i<arr.length - 1; i++) {
for (int j = 0; j< arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
4、折半查找法
限制:只能用于有序的数组。
需求:定义一个函数接收一个数组对象和一个要查找的目标元素,函数要返回该目标元素在数组中的索引值,如果目标元素不存在数组中,那么返回-1表示。
思想:定义三个变量分别记录最小、最大、中间索引值。然后用目标值和中间值进行比较,如果目标值大于中间值则最小值=中间值 + 1;如果目标值小于中间值则最大值 = 中间值 - 1;判断完之后,每次都要重置中间值。直到最大值小于最小值结束。
code:
//折半查找法
public static int binnarySearch(int[] arr,int target) {
int min = 0;
int max = arr.length - 1;
int mid = (max + min)/2;
while (max >= min) {
if (target > arr[mid]) {
min = mid + 1;
}else if (target < arr[mid]) {
max = mid - 1;
}else{
return mid;
}
mid = (max + min)/2;
}
return -1;
}
5、翻转数组
需求:定义 一个函数接收一个char类型的数组对象,然后翻转数组中的元素。
思想:利用循环,首尾对调。知道开始位置大于结束位置为止。
code:
//翻转数组:
public static char[] reverseArray(char[] arr) {
int startIndex = 0;
int endIndex = arr.length - 1;
while(endIndex > startIndex){
char temp = arr[startIndex];
arr[startIndex] = arr[endIndex];
arr[endIndex] = temp;
startIndex ++;
endIndex --;
}
return arr;
}
二维数组:数组中的数组。
二维数组的定义格式:
数据类型[][] 变量名 = new 数据类型[长度1][长度2];
注意:二维数组的长度取决于长度1。
二维数组的初始化方式:
动态初始化:
数据类型[][] 变量名 = new 数据类型[长度1][长度2];
静态初始化:
数据类型[][] 变量名 = {{元素1,元素2...},{元素1,元素2...},{元素1,元素2...} ..}
二维数组的遍历:需要使用嵌套循环来遍历
code:
int[][] arr = {{10,11,9},{67,12},{33,35,39,40}};
//遍历二维数组
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();
}