------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
Java基础(三):数组
一、数组
1.数组的定义
2.数组的内存分配特点:
3.数组操作的常见问题
4.数组的常见操作
5.数组中的数组---二维数组
1.数组的定义
定义:同一种类型数据的集合,其实数组就是一个容器
好处:可以自动给数组中的元素从0开始编号,方便操作元素
格式 1:元素类型 [ ] 数组名 = new 元素类型 [元素个数或数组长短] 实例:int [ ] arr = new int [34];
注意:a、new是引用数据类型!b、元素类型即元素的数据类型(int, short)
格式2: 元素类型 [ ] 数组名 = new 元素类型 [ ] {```数据1,数据2,```} ----使用大括号‘ { } ’
元素类型 [ ] 数组名 = {``数据1,数据2,数据3```}
示例:int [ ] arr1 = new int [ ] { 1, 2, 3, 4} ; 注意:为了防止混乱角标,new中的数据个数可以不填写
int [ ] arr2 = { 2, 3, 4, 5, 5};
二、数组在内存中的分配特点
1、数组分配在栈内存和堆内存中;
2、栈内存的特点:
a、数据使用完毕后,自动释放;b、多用于存放局部变量(如循环内的变量等)
堆内存的特点:
a、存放实体数据;b、为每一个分配地址(可被栈内存中的变量调用);c、垃圾回收机制(自动清理无效的数组)
3、当数组被定义,数组在堆中有默认初始化赋值,int是0,float是0.0f,boolean是false,等等。
4、每一个数据在堆中都有一个角标(下标),从0开始计算,x[0]代表第一个数字
图示更清楚:
三、数组操作中的常见问题
//数组使用易错点:
class{
public static void main(String[] args){
int[] arr1 = new int[5];
System.out.println(arr1[5]);
/* 错点:
java.lang.ArrayIndexOutOfBoundsException: 5
运行出错,编译不报错:访问到了数组中不存在的角标(下标)
因为数组是从0开始分配
*/
int[] arr2 = new int[] (1, 2, 3, 4);
arr2 = null;
System.out.println(arr2[2]);
/* 错点:
java.lang.NullPointerException-------空指针异常
空指针情况:
因为arr2已经为空,不再指向数组,也就无法输出arr2[2]中任何数据
*/
}
}
、
/*
* 数组常见操作----获取最值
*
* [2,4,1,33,99,66]
* 获取数组中的最大值,以及最小值
*
* 思路:
* 1.需要比较
*
*/
class arrayTest1 {
/* 需求:获取数组中的最大值
* 思路:
* 1、通过将数组中每一个元素进行比较获得最大值,我们先定义一个变量,临时存储一个元素,再用其他元素变量比较,较大者赋值给变量,再与下一个元素比较
* 2、当全部元素比较完毕,变量中的值就是数组中的最大值
* 步骤:
* 1、定义变量,初始化数组的第一个元素
* 2、通过循环语句遍历数组,
* 3、在遍历时定义判断条件,将遍历到的元素较大者赋给变量
*
* */
//需要定义一个公功能:
//返回值类型:一个值,int; 参数类型:一个数组,int[];
public static int getMax(int[] arr){
int max = arr[0];
for(int x=1; x
2、选择排序
class arrayTest2{
/*选择排序
* 特点:第一圈排序后,最值出现在第一个!
* */
//定义函数时,返回值类型是void。因为在函数的中的变量在栈内存找那个,
//变量指向了在堆内存中的数组,所以变量可以直接修改数组,而无需返回一个数组
public static void select(int[] arr){
for( int x=0; x
3、冒泡排序
class arraryTest3{
/*冒泡排序
* 特点:第一圈后,最值出现在最后!
* */
public static void bubble(int[] arr){
for(int x=0; x
4、折半查找法
/*
* 数组的查找:折半查找
*
*/
class arrayTest4{
public static void main(String[] args){
//折半查找
int[] arr2 = {22,33,44,55,66,77,88};
int index2 = halfSearch(arr2,55);
System.out.println("第一种折半查找方法index=" + index2);
int[] arr3 = {22,33,44,55,66,77,88};
int index3 = halfSearch2(arr3, 22);
System.out.println("第二种折半查找方法index=" + index3);
}
//折半查找1:数组必须是有序的!!!
public static int halfSearch(int[] arr, int key){
int min,mid,max;
min = 0;
max = arr.length;
mid = (min + max)/2;
while(key != arr[mid]){
if (key > arr[mid]) //如果所查值大于数组中间值,则:
min = mid +1; //将最小下标min=min+1;缩小范围
else if(key < arr[mid]) //如果所查值小于数组中间值,则:
max = mid -1; //将最大下标max=max-1,同样是为了缩小范围
if (min > max) //如果最后发现最小下标值大于了最大下标值,说明此数组不包含所查值
return -1; //所以返回-1
mid = (max+min)/2;
}
return mid;
}
//折半查找2: 优化第一种方法,效果一样
public static int halfSearch2(int[] arr, int key){
int min=0, max=arr.length-1,mid;
while(min<=max){
mid = (max+min) >> 1; //此语句效果等同于mid=(max+min)/2; 但位运算的速度快于除法运算,所以使用位运算,
if(key > arr[mid])
min = mid + 1;
else if(key < arr[mid])
max = max - 1;
else
return mid;
}
return -1;
}
//练习:将一个元素,插入一个有序的数组之中,插入之后,数组仍是有序的。
public static int halfSearch3(int[] arr, int key){
int min=0,max=arr.length-1,mid;
while(min<=max){
mid=(max+min)/2;
if(key > arr[mid])
mid = min + 1;
else if(key < arr[mid])
mid = max - 1;
else
return mid;
}
return min; //只需要修改最后的返回值即可,即当有序数组中没有插入元素时,min会大于max,
//最后的min就是插入元素的位置
}
}
附图:
5、查表法:十进制转换十六进制
//查表法
/*
* 查表法:将所有元素临时存储起来,建立对应关系,
* 每一次&15后的值直接作为索引去查建立好的表,就可以找到对应关系
*
* 0 1 2 3 4 5 6 7 8 9 10 A B C D E F ---十六进制
*
* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ----对应的角标
*
* 建表方式:通过数组的形式来定义!
*/
class arrayTest6{
public static void main(String[] args){
toHex(60);
}
public static void toHex(int num){
char[] chs = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E'};
/* for(int x=0; x<8; x++){
int temp = num & 15;
System.out.println(chs[temp]);
num = num >>> 4;
}*/
//定义一个临时数组,用来存储转换后的元素
char[] arr = new char[8];
//定义一个指针,用于操作临时数组
int pos = arr.length;
while(num != 0){
int temp= num & 15;
arr[--pos] = chs[temp]; //arr[--pos]:倒着存放元素
num = num >>> 4; //将num向右移动4位
}
for(int x=pos; x
附图:
6、十进制---->二进制、八进制、十六进制
/*
* 进制转换的查表法的最终优化--通用表
*
*/
class arrayTest7{
public static void main(String[] args){
// toBin(6);
// toBa(60);
toHex(60);
}
/*十进制-->二进制*/
public static void toBin(int num){
trans(num, 1, 1);
}
/*十进制-->八进制*/
public static void toBa(int num){
trans(num, 7, 3);
}
/*十进制-->十六进制*/
public static void toHex(int num){
trans(num, 15, 4);
}
public static void trans(int num, int base, int offset){
//num表示需要转换的十进制,
//base表示转换进制的位数,----八进制的base为2^3 - 1 十六进制的base为2^4 - 1;
//offset表示num向右移位的位数-----八进制为3位, 十六进制为4位
char[] chs = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E'};
//定义一个临时存储,用于存放转换后的元素
char[] arr = new char[32];
//定义一个指针,用于操作临时数组
int pos = arr.length;
while(num != 0){
int temp = num & base;
arr[--pos] = chs[temp];
num = num >>> offset;
}
for(int x=pos; x
五、二维数组
格式1:int [ ] [ ] arr = new arr [ 3 ] [ 2 ] ;
-
定义了名称为arr的二维数组
-
二维数组中有3个一维数组
-
每一个一维数组中有两个元素
-
一维数组的名称为 arr[0] , arr[1], arr[2]
-
如果给一个一维数组1赋值98,写法是:arr[0][1] = 98;
附图:
格式2:Int [ ] [ ] arr = new [3] [ ];
-
二维数组中有3个一维数组
-
每一个一维数组都默认初始值null
-
可以对这3个一维数组分别初始化
-
arr [0] = new arr[3];
-
arr [1] = new arr[2];
-
arr [2] = new arr[1];
格式3:int [ ][ ] arr = { {``元素``},{``元素``},{``元素``} };
//二维数组
class array2Demo{
public static void main(String[] args){
//第一种定义方式:
int[][] arr1 = new int [3][2]; //定义了一个二维数组,它由3个一维数组组成,每个一维数组中2个元素
arr1[0][1] = 12;
// arr1[1][2] = 33; // java.lang.ArrayIndexOutOfBoundsException: 2
//定义失败,下标越界,无法赋值
//第二种定义方式:
int[][] arr2 = new int[3][]; //值定义二维数组的长度为3,不定义每个数组的元素
//为每一个数组定义元素长度
arr2 [0] = new int[3]; //如:为arr2[0]定义一个含有3个元素的一维数组
arr2 [1] = new int[4]; //如:为arr2[1]定义一个含有4个元素的一维数组
arr2 [2] = new int[5];
//第三种定义方式:
int[][] arr3 = {{2,5,1,6}, {9,8,6,55},{33,44,55,123}};
int sum = 0;
for(int x=0; x