黑马程序员--数组

来源:互联网 发布:热力学数据计算软件 编辑:程序博客网 时间:2024/06/07 01:06

                                                                                        ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

1.数组:

1.1数组的定义

概念:

                   同一种类型数据的集合,其实数组就是一个容器

         数组的好处:

                   可以自动给数组中的元素从0开始编号,方便操作这些元素

         格式1:

                   元素类型[] 数组名=new 元素类型[元素个数或数组长度]

         格式2:

                   元素类型[] 数组名=new 元素类型[]{元素,元素,……};

         int[]arr = new int[4];

 int[]arr = new int[]{3,5,1,7};

         int[]arr = {3,5,1,7};

1.2数组的内存分配及特点

Java程序在运行时,需要在内存中分配空间.为了提供运算效率,对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式

栈内存:

         用于存储局部变量,当数据使用完,所占空间会自动释放

         注:只要定义的局部变量,都是在栈内存中开辟内存空间

 局部变量:

1.     定义在方法中的变量,

2.     定义在方法中参数列表中的变量,

3.     定义在for循环中的变量

堆内存:

         数组和对象,通过new建立的实例都存放在堆内存中

         每一个实体都有内存地址值

         实体中的变量都有默认初始化值

         当实体不再被使用时,会在不确定的时间内被垃圾回收器回收

int[] x=new int[3];      //new了之后会在对内存中开辟空间,会把首地址赋给x

数组一被定义都会赋初值

堆内存中的实体都是封装数据的,每个实体都有默认初始化值

int[] x=new int[3];

当x=null 的时候,就会把栈内存和对内存之间的桥梁断开,也就是null会把堆内存中开辟的空间数组的首地址覆盖掉

这时jvm的垃圾回收机制会把垃圾不定时的回收掉

当一个实体类为null时,不会在堆内存中开辟内存空间

当new的时候,会在堆内存中开辟内存空间

:

         栈内存会自动释放

         堆内存会通过垃圾回收机制不定时释放

例:两个引用指向同一个对象

int[] x=new int[3];int[] y=x;y[0]=89;x[0]=77;x=null;System.out.println(y[0]);

注意:数组静态初始化

int[] x=new int[]{1,2,3,4,5};int[] x={1,2,3,4,5};//与上面的完全等价,也会在堆内存中开辟空间

常见错误:

int[] x=new int[3];System.out.println(x[3]);//在编译时不会报错,因为编译只会检查语法错误,运行时才会开辟堆内存空间

打印数组变量的结果:


方法区:

这里包括(类:字节码文件对象、静态区、常量池)

     存放静态成员变量和静态方法,存放类的模板,方法区中有一个常量池,在常量池中存放字符串常量String ,其存放方式跟栈内存中局部变量的存放相似:假设要存放字符串“abc”(通过String x =“abc”;的方式),则先查找常量池中有没有“abc”的对象,若有则返回一个此对象的引用给x,若不存在则   开辟一个新的空间存放此字符串,并让x引用该对象。如果是通过String x = new String(“abc”);的方式则首先会在堆内存中new一个对象,存放“abc”,并将该对象的引用传给x,然后查看常量池中是否存在“abc”,若存在则将堆内存中的对象与之关联,若不存在,则在常量池中开辟一个空间存放“abc”,并将堆内存中的对象与之关联。若是将两个字符串拼接到一起时则会在堆内存中创建一个对象,存放拼接后的字符串,若要使拼接的字符串存放于常量池中则要用到intern()方法,具体用法:x = (s1+s2).intern(),s1 s2为待拼接的字符串。

1.3数组操作常见问题

空指针:NullPointerException

数组溢出:ArrayIndexOutOfBoundsException

1.4数组常见操作

找最值:

两种方法:一种是根据脚标,一种是根据内容
public static void getMax(int[] arr){//根据内容查找int flag=arr[0];for(int i=1;i<arr.length;i++){if(flag<arr[i]){flag=arr[i];}}System.out.println(flag);}public static void getMax_2(int[] arr){//根据脚标查找int flag=0;for(int i=1;i<arr.length;i++){if(arr[flag]<arr[i]){flag=i;}}System.out.println(arr[flags]);}public static void getMin(int[] arr){//找最小值int flag=arr[0];for(int i=1;i<arr.length;i++){if(flag>arr[i]){flag=arr[i];}}System.out.println(flag);}

排序:

      选择排序:

public static int[] toMax(int[] x){for(int i=0;i<x.length-1;i++){for(int j=i+1;j<x.length;j++){if(x[i]<x[j]){x[i]=x[i]+x[j];x[j]=x[i]-x[j];x[i]=x[i]-x[j];}}}return x;}

冒泡排序:
public static void bubbleSort(int[] x){for(int i=0;i<x.length-1;i++){for(int j=0;j<x.length-i-1;j++){if(x[j]<x[j+1]){exchange(x,j,j+1);}}}}

在开发中如果对数组进行排序,使用Arrays.sort() 方法进行

最快的排序是希尔排序(三层循环+位运算)

堆内存中数组换位是比较占资源的,完全可以记录排序的位置(放在占内存中),最后进行位置转换

查找操作:查找的都是数组中第一次出现的位置

普通查找:
public static int find(int[] arr,int key){for(int i=0;i<arr.length;i++){if(key==arr[i])return i;}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(arr[mid]!=key){if(key<arr[mid]){    max=mid-1;}else if(key>arr[mid]){    min=mid+1;}if(min>max)return -1;mid=(min+max)/2;}return mid;}

方法二:判断前后两个脚标的是否重合
public static int halfSearch_2(int[] arr,int key){    int min=0,max=arr.length-1,mid;while(min<=max){mid=(min+max)>>1;//和(min+max)/2效果相同,但是效率更高    if(key<arr[mid]){    max=mid-1;}else if(key>arr[mid]){min=mid+1;}else{    return mid;}}return -1;}
扩展:往一个有序的数组中插入一个数字,保证数组还是有序的
思路:返回的是min的脚标
public static int getIndex(int[] arr,int key){    int min=0,max=arr.length-1,mid;while(min<=max){mid=(min+max)>>1;//和(min+max)/2效果相同,但是效率更高    if(key<arr[mid]){    max=mid-1;}else if(key>arr[mid]){min=mid+1;}else{    return mid;}}return min;}

进制转换:

十进制转二进制:

public static void toBin(int num){char[] c={'0','1'};char[] arr=new char[32];//int类型最大32位int point=arr.length;while(num!=0){int temp = num&1;arr[--point] = c[temp];num = num>>>1;//相当于除2,补0}for(int i=point;i<arr.length;i++){System.out.print(arr[i]);}}

十进制转十六进制:

<span style="font-weight: normal;">public static void toHex(int num){char[] c={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};char[] arr=new char[8];//int类型变为16进制最多为8位int point=0;while(num!=0){int temp=num&0xf;arr[point++] = c[temp];num=num>>>4;}for(int i=point-1;i>=0;i--){//point在最后又加了一次,需要减1System.out.print(arr[i]);}}</span>

在两个方法中相同的

1.      都要定义表(十六进制的表包含二进制的表)

2.      都有存储数组(二进制的32位包含十六进制的8位)

3.      都要定义标记位

两个方法不同的

1.      与的数字不同

2.      位运算的数字不同

抽出一个公有方法:

<span style="font-weight: normal;">public static void trans(int num,int x,int y){//x为与运算的值,y为位运算的值     if(num==0){          System.out.println(num);          Return ;     }<span style="white-space:pre"></span>char[] tab={'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){int temp=num&x;arr[--pos]=tab[temp];num=num>>>y;}//System.out.println(pos);for(int i=pos;i<arr.length;i++){System.out.print(arr[i]);}}</span>
使用方法调用:

<span style="font-weight: normal;">public static void toBin(int num){trans(num,1,1);   }public static void toEight(int num){trans(num,7,3);}public static void toSixty(int num){trans(num,15,4);}</span>

1.5数组中的数组--二维数组



内存开辟情况:


二维数组初始化:

1.  int[][] arr=new int[2][3];

此含义是定义一个二维数组,他的二维数组长度是2,里面每个一维数组的长度为3

当输出arr时,输出的是内存地址的值

当输出arr[1]时,输出的也是内存地址的值,区别是前面的标示不同,前者为[[(标示二维数组),后者为[(标示一维数组)

当输出arr[1][1]时,输出的结果为0,因为一维数组定义的默认值为0

2.  int[][] arr=new int[3][];

此含义只是定义了一个长度为3的二维数组,每个一维数组的长度没有定义

当输出arr时,输出的是内存地址

当输出的是arr[1]时,输出的结果为null,因为此数组只定义了二维数组的长度,而一维数组却没有定义,我们知道,数组,类,和接口都是引用数据类型,在没有定义时默认值为null

我们可以对二维数组中的一维数组进行初始化

arr[0]=new int[3];            //第一个一维数组的长度为3

arr[1]=new int[2];            //第二个一维数组的长度为2

arr[2]=newint[4];            //第三个一维数组的长度为4

其他定义方式(不常用,但是见了要认识)

int[ ][ ] y
int y[ ][ ]
int[ ] y[ ]

                                                                                     ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

0 0
原创粉丝点击