文章目录
数组定义与使用
1.数组的基本用法
1.1什么是数组*
相同数据类型的集合,内存是连续的
1.2创建数组
数据类型[] 数组名称=new 数据类型[数组长度]
int[] array=new int[5];//定义好了数组没有初始化,默认为0,new产生一个对象
int[] array1=new int[]{1,2,3};//动态初始化
int[] array2={1,2,3};//静态初始化
array 为一个引用类型变量,存放的是首元素的地址
Int[] array={ }//长度为0
System.out.print(array.length);//空指针异常
String str=null;//null是所有引用变量的初始化
System.out.println(str.length);//空指针异常
array.length能够获得数组长度[0,length-1],length为一个属性
String str="asdfef";//6
System.out.println(str.length());//length( )为方法
int[] arr=new int[4];
System.out.println(arr[100]);//java.lang.ArrayIndexOutOfBoundsException数组越界
1.3遍历数组
1.int[] array={1,2,3};
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
2.int[] array={1,23,4,5};
for(int x:arr)
System.out.println(x);
for-each(表达式1:表达式2)
for循环和for-each循环的区别:
1.for-each当中的值不能用下去标访问
2.for循环次数多,for-each可以避免循环条件和更新语句的写错
2.数组作为方法的参数
2.1基本用法
打印数组内容
public static void printArray(int[] array){
for(int x:array)
System.out.println(array);
}
2.2理解引用类型
public class Test{
public static void main(String[] args){
int num=0;
func(num);
System.out.println(num);
}
public static void func(int x ){
x=10;
System.out.println("x ="+ x);
}
}//num=0,x=10
过程如图:
修改x的值,不影响实参的值
参数传数组类型:
public class Test{
public static void main(String[] args){
int[] array={1,2,3};
func(num);
System.out.println(num);
}
public static void func1(int[] a){
a[0]=10;
System.out.println(a[0]);
}
}//a[0]=10,array[0]=10
int[ ] a=array
修改a[0]的值
2.3jVM内存区域
》程序计数器:只是一个很小的空间,保存下一条指令的地址
》虚拟机栈:存储局部变量表,例如int[] arr
》本地方法栈:保存的是native方法局部变量,底层有c/c++实现
Native 方法就是指这些 C++ 实现的, 再由 Java 来调用的函数
JVM 是一个基于 C++ 实现的程序. 在 Java 程序执行过程中, 本质上也需要调用 C++ 提供的一些函数进行和操作系统底层进行一些交互. 因此在 Java 开发中也会调用到一些 C++ 实现的函数
》堆:JVM管理的最大内存区域,使用new创建的对象在堆上保存
》方法区:用于存储已被虚拟机加载的类的信息,常量,静态变量,即使编译器编译后的代码等数据,字节码文件也保存在这个区域
》运运行时常量池:存放字面量与符号引用,例如String str=" hello"中的**“hello”**就存放在里面
2.4数组转字符串
1. Arrays.toString( )//Arrays当中操作数组的工具类
2.public static String toString(int[] array) {
String ret = "[";
for (int i = 0; i < array.length; i++) {
ret += array[i];
if (i != array.length - 1)
ret+= ",";
}
ret += "]";
}
2.5拷贝数组
1.public static int[] copyArray(int[] array,int[] array2){
array2=new int[array.length];
for(int i=0;i<array.length;i++){
array2[i]=array[i];
}
return array2;
}
2.Arrays.copyOf(arr,arr.length)arr原数组,arr.length复制数组的长度,只能从起始位置开始复制
int[] newArr=Arrays.copyOf(array,array.length);
System.out.println(Arrays.toString(newArr));
3.arraycopy()方法
函数原型:arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
src: 原数组 srcPos:原数组起始的位置
dest:目的数组 destPos:目的数组的起始位置
length:所需复制数组的长度
需要注意的是要重新声明一个同类型且长度足够的数组,否则会出现异常
int[] newArr1=new int[array.length];
System.arraycopy( array,0,newArr1,0,3);
System.out.println(Arrays.toString(newArr));
4. int[] newArr2=new int[array.length];
newArr2=array.clone( );
System.out.println(Arrays.toString(newArr2))
5.System.arraycopy( )和Arrays.copyOf( )的区别和联系:
arraycopy被native所修饰的方法,运行速度快
copyOf方法内部调用了arraycopy,方法的返回为数组
2.6二分查找*
前提:有序
N*(1/2)^Y=1;
时间复杂度: Y = Log2N.
1.public static int binarySearch(int[] array,int toFind){
int left=0;
int right=array.length;
while(left<right) {
int mid = (left + right) / 2;
//在左半区
if (toFind < array[mid]) {
right = mid - 1;
} else if (toFind >array[ mid]) {//在右半区
left = mid + 1;
} else {
return mid;
}
}
return -1;//没有找到
}
2.二分查找递归
public static int binarySearch(int[] array,int key,int left,int right) {
if (left > right) {
return -1;//没有找到
}
int mid = (left + right) / 2;
if (array[mid] == key) {//找到key
return mid;
} else if (array[mid] > key) {//在前半部分
return binarySearch(array, key, left,mid - 1);
} else {//在后部分
return binarySearch(array, key, mid + 1,right);
}
}
3.Arrays.binarySearch( )前提为有序
》binarySearch(T[ ] a, int fromIndex, int toIndex, T key)
使用二进制搜索算法搜索指定对象的指定数组的范围。
a:要搜索的数组
fromIndex:指定范围的开始处索引(包含)
toIndex:指定范围的结束处索引(不包含)
key:要搜索的值
如果要搜索的元素key在指定的范围内,则返回搜索值的索引;否则返回-1或“-”(插入点)。
程序:
int arr [] =new int[]{1,3,4,5,8,9};
System.out.println(arr.length+1);
Arrays.sort(arr);
int index5 = Arrays.binarySearch(arr,1, 4, 6);
int index6 = Arrays.binarySearch(arr,1, 4, 4);
int index7 = Arrays.binarySearch(arr,1, 4 ,2);
int index8 = Arrays.binarySearch(arr,1, 3, 10);
int index9 = Arrays.binarySearch(arr,1, 3, 0);
System.out.println("index5 = "+ index5 +", index6 = " + index6 +
", index7 = " + index7 +", index8 = "+ index8 +“,index”+index9);
结果:index5 = -5, index6 = 2,index7 = -2, index8 = -4, index9 = -2
》binarySearch(Object[], Object key)
a: 要搜索的数组
key:要搜索的值
如果key在数组中,则返回搜索值的索引;否则返回-1或“-”(插入点)。插入点是索引键将要插入数组的那一点,即第一个大于该键的元素的索引。
程序:
int arr [] =newint[]{1,3,4,5,8,9};
Arrays.sort(arr);
int index1 = Arrays.binarySearch(arr,6);
int index2 = Arrays.binarySearch(arr,4);
int index3 = Arrays.binarySearch(arr,0);
int index4 = Arrays.binarySearch(arr,10);
System.out.println("index1 = "+ index1 +", index2 = " + index2 +
", index3 = " + index3 +", index4 = "+ index4);
结果:index1= -5, index2 = 2, index3 = -1, index4 = -7
2.7数组排序
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
N个数字要排序完成,总共进行N-1趟排序,每i趟的排序次数为(N-i)次
冒泡排序总的平均时间复杂度为:O(n2) 。
1.冒泡排序
public static void bubbleSort(int[] array){
//趟数
for(int i=0;i<array.length-1;i++){
//两两比较
for(int j=0;j<array.length-i-1;j++){
if(array[j]>array[j+1]){
int temp=array[j];
array[i]=array[j+1];
array[j+1]=temp;
}
}
}
}
2.Arrays.sort(arr);
2.7数组逆置
public static void reverse(int[] array) {
int left = 0;
int right = array.length - 1;
while (left < right) {
int temp=arr[left];
arr[left]=arr[rigth];
arr[rigth]=temp;
left++;
rigth--;
}
}
数组数字排列,奇数在前,偶数在后
public static void m(int[] array) {
int left=0;
int right=array.length-1;
while(left<right){
//该循环结束,指向一个偶数
while(left<right&&array[left]%2!=0){
left++;
}
//该循环结束,指向一个奇数
while(left<right&&array[right]%2==0){
right--;
}
if(left<right){
int temp=array[left];
array[left]=array[right];
array[right]=temp;
}
}
}