数组的定义
同一种类型数据的集合,其实数组就是一个容器。数组是一种引用数据类型,区别于基本数据类型
格式:
1、元素类型[] 数组名 = new 元素类型[元素个数或数组长度];2、元素类型[] 数组名 = new 元素类型[]{元素,元素,...};//静态初始化
元素类型[] 数组名 = {元素,元素,...};
内存结构
Java程序运行时,需要在内存中分配空间。为了提高运算效率,又对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。栈内存:
用于存储局部变量,当数据使用完,所占空间会自动释放局部变量:定义在方法中,方法参数上和for循环里面的变量。
堆内存:
数组和对象,通过new建立的实例都存放在堆内存中每一个实体都有内存地址值
实体中的变量都有默认初始化值
实体不再被使用,会在不确定的时间内被垃圾回收器回收
方法区、本地方法区、寄存器
堆内存中的每一个实体都有一个内存地址值
堆内存中的数据都有默认初始化值(int:0 doule:0.0 float:0.0f boolean:false)
x = null;//x不再指向该数组,只有引用数据类型才能使用null,之后就会调用垃圾回收器。
示例图如下:
操作数组的常见问题:
编译只检查语法错误,不检测运行错误ArrayIndexOutOfBoundsException:3:操作数组时,访问到了数组中不存在的角标
NullPointerException:空指针异常:当引用没有任何指向值为null的情况,该引用还在用于操作系统实体
数组的常见操作:
获取元素
获取数组中的元素,通常会用遍历。[I@de6ced:是一个数组的地址
获取最值
步骤:1、定义临时变量。初始化为数组中任意一个元素即可
2、通过循环对数组进行遍历
3、在变量过程中定义判断条件,如果遍历到的元素比变量中的元素大/小,就赋值给该变量
也可以将临时变量初始化为数组中任意一个角标
对数组排序
选择排序:
所定义的函数不需要返回值,因为至始至终在堆内存里面是同一个数组代码如下:
public static void selectSort(int[] arr)
{
for(int x=0; x<arr.length-1; x++)
{
for(int y=x+1; y<arr.length; y++)
{
if(arr[x]>arr[y])
{
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
}
}
特点:内循环结束一次,最值出现在0角标位置上冒泡排序:
相邻的两个元素进行比较,如果符合条件换位代码如下:
public static void bubbleSort(int[] arr)
{
for(int x=0; x<arr.length-1; x++)//for(int x=arr.length-1; x>0; x--)
{ //for(int y=0; y<x; y++)
for(int y=0; y<arr.length-x-1; y++)//-x:让每一轮比较的元素减少。-1::避免角标越界,因为y+1的最大值是4,当x取0的时候y+1才小于arr.length
{
if(arr[y+1]<arr[y])
{
int temp = arr[y];
arr[y] = arr[y+1];
arr[y+1] = temp;
}
}
}
}
特点:第一圈内循环结束一次:最值出现在数组的最后一位该方式在每一次循环中堆内存中置换了很多次,消耗资源,可以考虑在栈内存中声明两个变量用于存储最终需要置换的元素的角标
Arrays.sort(arr);//java中已经定义好的一种排序方式,真实开发使用
可以把对元素位置置换的代码提取出来,单独封装成一个函数,注意要传三个参数:
swap(int[] arr, int a, int b)
数组的查找操作
普通查找
//定义功能:获取key第一次出现在数组中的位置,如果返回-1,代表该key不存在
public static int getIndex(int[] arr, int key)
{
for(int x=0; x<arr.length; x++)
{
if(arr[x]==key)
return key;
}
return -1;
}
折半查找
折半查找的第一种方式:
可以提高效率,但必须保证数组是有序的 public static int halfSearch(int[] arr, int key)
{
int min,max,mid;
min = 0;
max = arr.length-1;
mid = (min+max)/2;
while(key!=arr[mid])
{
if(key>arr[mid])
min = mid+1;
else if(key<arr[mid])
max = mid-1;
if(min>max)
return -1;
mid = (max+min)/2;
}
return mid;
}
折半查找的第二种方式:
public static int halfSearch_2(int[] arr, int key)
{
int min,max,mid;
min = 0;
max = arr.length-1;
while(min<=max)//判断条件不一样
{
mid = (min+max)/2;
if(key>arr[mid])
min = mid+1;
else if(key<arr[mid])
max = mid-1;
else
return mid;
}
return -1;
}
将-1改为min可以返回给定的要插入的数的位置来保证数组有序利用数组进行进制转换
十进制-->二进制
public static void toBin(int num)//该方法有局限性,num不能为负数。考虑用查表法,然后利用>>>来取到有效位
{
StringBuffer sb = new StringBuffer();
while(num>0)//当num = 1/2时,因为num为int型,所以num = 0
{
sb.append(num%2);
num = num/2;
}
System.out.println(sb.reverse());//将Stingbuffer中的数反转并输出
}
Java提供toBinaryString();十进制-->十六进制
public static void toHex(int num)
{
StringBuffer sb = new StringBuffer();
for(int x=0; x<8; x++)//一个int型整数是4个字节,这里可以while(num!=0),这样就没有前面的0了
{
int temp = num&15;
if(temp>9)
sb.append((char)(temp-10+'A'));//减去数字基数,加上字母基数,运算要加上括号,否则会出错
else
sb.append(temp);
num = num>>>4;
}
Sop(sb.reverse());
}
查表法
可以计算负数,通用方法利用元素和数组角标的对应关系,每一次&15后的值作为索引去查建立的表。比-10+'a'简单得多
字符数组中默认值为'\u0000'
public static void toHex(int num)
{
char[] chs = {'0','1','2','3',
'4','5','6','7',
'8','9','A','B',
'C','D','E','F'};
char[] arr = new char[8];
int pos = arr.length;//定义指针记录数组中有效位的起始位置
while(num!=0)//如果有效为已经操作完毕,那么num会变为0
{
int temp = num&15;
arr[--pos] = chs[temp]; //pos先改变值再参与语句,这样pos就指向了有效位的起始位置
num = num>>>4;
}
for(int i = pos;i<arr.length;i++)
{
System.out.print(arr[i]);
}
}
抽取功能共性,优化代码。num,&的数,偏移位都未知,这样2,8,16进制都可以转换 public static void trans(int num, int base, int offset)
{
if(num == 0)//如果num为0,则直接打印
{
System.out.println(0);
return;
}
char[] chs = {'0','1','2','3',
'4','5','6','7',
'8','9','A','B',
'C','D','E','F'};
char[] arr = new char[32];
int pos = arr.length;//定义指针记录数组中有效位的起始位置
while(num!=0)//如果有效为已经操作完毕,那么num会变为0
{
int temp = num&base;
arr[--pos] = chs[temp]; //pos先改变值再参与语句,这样pos就指向了有效位的起始位置
num = num>>>offset;
}
for(int i = pos;i<arr.length;i++)
{
System.out.print(arr[i]);
}
}
二维数组
把数组作为元素存到了另一个数组当中格式1:
int[][] arr = new int[3][2];
格式2:
int[][] arr = new int[3][];
int arr[][]和int[] arr[]也行;
二维数组中有3个一维数组
每个一维数组都是默认初始化值null(因为数组是引用数据类型)
可以对这三个一维数组分别进行初始化:
arr[0] = new int[3];
arr[1] = new int[1];
arr[2] = new int[2];
int[] x,y[];//x是一维,y是二维,相当于 int[] x; int[] y[];中括号跟着类型走,变量都有效,中括号跟着变量走,只有该变量有效