java---数组

5.0数组

5.0.1数组的定义

a)  概念

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

b)  数组的好处

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

c)  格式1

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

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

(以上两种格式都可以,以第一种格式居多)

示例:int[] arr= new int[5];

d)  格式2(静态初始化方式)

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

int[] arr = new int[]{3,5,1,7};//此时数组不写长度

int[] arr={3,5,1,7};//也可简写为此

5.0.2数组的内存结构图示


2.  数组的内存分配及特点

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

a)   栈内存

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

b)  堆内存

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

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

   iii.     实体中的变量都有默认初始化值(以数据类型确定)

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

5.0.4数组操作常见问题

c)  数组脚标越界异常

       i.     英文为:ArrayIndexOutOfBoundsException

     ii.     编译通过(只检查语法错误),new在运行后才会建立,并在堆内存中建立空间

int[] arr = new int[2];

System.out.println(arr[3]);

   iii.     访问到了数组中的不存在的脚标时发生。

d)  空指针异常

       i.     英文为:NullPointerException

     ii.     编译通过(只检查语法错误),运行时没有指向

int[] arr =null;

System.out.println(arr[0]);

   iii.     arr引用没有指向实体,却在操作实体中的元素时。

e)  打印出数组地址

       i.     int[] arr ={2,4,6,7};

     ii.     System.out.println(arr);

   iii.     运行结果:[I@6bbc4459:分解说明:[(数组类型)I(int型)@(地址)6bbc4459(通过哈希算法算出的内存中的地址值是一个哈希值,是一个十六进制)。

     iv.     [I@6bbc4459:打印了一个数组实体的引用

5.0.5数组常见操作

f)  获取最值(最大值、最小值)(适合于数值型数组)

       i.     在为max和min赋初始化值的时候,可以有两种方式:

1.  int max = arr[0];赋值为数组的第一个元素;

2.  int max = 0;赋值为数组的脚标值,代码如下:if(arr[x]>arr[max])

max=x;System.out.println(arr[max]);

g)  排序(选择排序、冒泡排序)

       i.     选择排序

1.  选择固定的一个位置和拿这个位置上的值,不断的和别的位置的值比较,若换完位以后还拿这个位置上的值,和其他位置的值进行比较。

2.  选择排序特点:内循环结束,最值出现在开始脚标位置

3.  关键代码如下:

//外循环排序

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;

                  }

     ii.     冒泡排序

1.  相邻的两个元素进行比较,如果符合条件换位。

2.  关键代码:

//外循环控制循环的轮数

for (int x=0;x<arr.length-1 ;x++ )

{//内层循环控制相邻的比较

   //-x:让每一次比较的元素减少,

   //-1:避免角标越界。

  for (int y =0;y<arr.length-x-1 ;y++ )

      {

         if(arr[y]>arr[y+1])

             {

                int temp =arr[y];

                arr[y] = arr[y+1];

                arr[y+1] =temp;

             }

       }

   iii.     最快的排序是:希尔排序,三层循环加上位运算

     iv.     java开发中要使用的代码:Arrays.sort(arr);此句代码需要引入:import java.util.*;

       v.     发现无论什么排序。都需要对满足条件的元素进行位置置换。所以可以把这部分相同的代码提取出来,单独封装成一个函数。

抽取交换的共性代码为一个函数的代码如下:

public static voidswap(int[] arr,int a,int b)

    {

       int temp = arr[a];

       arr[a] = arr[b];

       arr[b] = temp;

}

h)  折半查找(二分查找)

       i.     当在数组中没有查找到结果时,一个惯例就是返回“-1”,因为java数组的脚标是不会出现负数的。一般查找的都是数组中的第一次出现该元素的位置。

     ii.     提高了效率,但是必须要保证该数组是有序的数组

java提供好的一个进行折半查找的功能。开发时使用(演示)

import java.util.*;

int x =Arrays.binarySearch(arr,90);

System.out.println("x="+x);

遍历数组:当要查找的元素与数组元素相同时(演示)

for(int x=0;x<arr.length; x++)

       {

           if(arr[x]==key)

              return x;

       }

       return -1;

折半查找:折半后的min和max比较判断循环

int min = 0,max =arr.length-1,mid;//脚标值

while(min<=max)   //满足就折半查找

       {

           mid = (max+min)>>1;

           if(key>arr[mid])//如果大于折半脚标

              min = mid + 1;//最小脚标为折半脚标+1

           else if(key<arr[mid])//如果小于折半脚标

              max = mid - 1;//最大脚标为折半脚标-1

           else

              return mid;//等于折半脚标就是找到元素

       }

       return -1;//找不到元素返回值-1

折半查找:用中间值和key比较来循环,移动min和max比较

     int min,max,mid;

       min= 0;   max = arr.length-1;

       mid= (max+min)/2;

while(arr[mid]!=key)//利用中间值和key比较

       {

           if(key>arr[mid])

              min= mid + 1;

           elseif(key<arr[mid])

              max= mid - 1;

    //之后比较min和max的值

           if(min>max)//越界,没有找到

              return-1;

       mid= (max+min)/2;//算出新的中间值继续

       }

       returnmid;

折半查找延伸:在有序数组中插入目标元素

int min = 0,max = arr.length-1,mid;

while(min<=max)

       {

           mid= (max+min)>>1;

           if(key>arr[mid])

              min = mid + 1;

           elseif(key<arr[mid])

              max= mid - 1;

           else

              returnmid;

       }

       returnmin;

i)  获取数组长度:数组长度 = 数组名.length

j)  遍历数组

       i.     使用for循环,数组长度

5.0.6数组中的数组

k)  二维数组[][]

       i.     格式1:int[][] arr = new int [3][2];

1.  定义了名称为arr的二维数组

2.  二维数组中有3个一维数组(二维数组的长度)

3.  每一个一维数组中由2个元素(二维数组中每一个一维数组的长度)

4.  一维数组的名称分别为arr[0],arr[1],arr[2]

5.  给第一个一维数组1脚标位赋值为78的写法:arr[0][1]=78;

6.  可以通过打印二维数组中的元素,明确二维数组的初始化特点,此格式下:

a)  打印System.out.println(arr);结果为:[[I@6bbc4459:二维数组int类型的哈希值;

b)  打印System.out.println(arr[]);结果为: [I@6bbc4459:一维数组int类型的哈希值;

c)  打印System.out.println(arr[0][0]);结果为:0它是一个二维数组元素;

     ii.     格式2:int[][] arr = new int [3][];

1.  二维数组中有3个一维数组

2.  每个一维数组都是默认初始化值null

3.  可以对这个三个一维数组分别进行初始化

arr[0] =new int [3];

arr[1] =new int [1];

arr[2] =new int [2];内存分配图:

在此情况下打印数组长度:

System.out.println(arr.length);//打印是二维数组的长度 3;System.out.println(arr[0].length);//打印二维数组中第一个一维数组长度3


4.  此格式下

a)  打印System.out.println(arr);结果为:[[I@6bbc4459:二维数组int类型的哈希值;

b)  打印System.out.println(arr[0]);结果为:null:为这个数组的默认初始化值,堆内存中开辟空间但是没有初始化值。

c)  打印System.out.println(arr[0][0]);结果为:NullPointerException

   iii.     格式3:int[][] arr = {{3,8,2},{2,7},{9,0,1,6}};

1.  定义一个名称为arr的二维数组

2.  二维数组中的有三个一维数组

3.  每一个一维数组中具体元素也都已初始化

4.  第一个一维数组arr[0]={3,8,2}

5.  第二个一维数组arr[1]={2,7}

6.  第三个一维数组arr[2]={9,0,1,6}

7.  第三个一维数组的长度表示方式:arr[2].length;

     iv.     练习:获取arr数组中所有元素的和。使用for的嵌套循环即可。

二维数组的应用:所有元素之和,关键代码如下:

int sum = 0;

    for(intx=0; x<arr.length;x++)

       {

           for(inty=0; y<arr[x].length; y++)

           {

              sum= sum + arr[x][y];

           }

       v.     注意特殊的写法:

1.  一维数组的写法:

a)  int[] x;

b)  int x[];

2.  二维数组的写法

a)  int[][] y;

b)  int y[][];

c) int[] y[];

3.  int[] x,y[];x是一维数组,y是二维数组。

5.0.7练习(进制转换)

l)  进制转换

     i.     十进制转二进制

关键代码:(红色代码也可以单独实现)

StringBuffer sb = new StringBuffer();

while(num>0)

       {

           //System.out.println(num%2);

           sb.append(num%2);

           num = num / 2;

       }

       System.out.println(sb.reverse());

    //输出反转

   ii.     十进制转十六进制

1. 关键代码:先&15,判符号,无符号右移

StringBuffer sb = new StringBuffer();

//int型数据4个字节32个二进制位,故8次移位

for(int x=0; x<8; x++)

    {

           inttemp = num & 15;

           if(temp>9)

    //System.out.println((char)(temp-10+'A'));

              sb.append((char)(temp-10+'A'));

           else

              //System.out.println(temp);

              sb.append(temp);

           num  = num >>> 4;

       }

       System.out.println(sb.reverse());

 iii.     查表法十进制十六进制

1.  将所有的元素临时存储起来,建立对应关系。

2.  每一次&15之后的值作为索引去查建立的表,就可以找对应的元素,这儿样比“x-10+’a’”方便。

3. 代码步骤:创建查询表,创建临时存储结果表,创建指针,通过循环将结果与指针相关联,右移,遍历打印。

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];

//定义一个指针,并指向最后一个元素,(倒着存)

       intpos = arr.length;

while(num!=0)//当num有效位右移完之后不循环

       {

           inttemp = num & 15;

           //System.out.println(chs[temp]);

//查询表,并将其存入临时表的最后一个空间中

           arr[--pos]= chs[temp];

           num= num >>> 4;//无符号右移

       }

System.out.println("pos="+pos);//打印指针的值

       //存储数据的arr数组遍历。

       for(intx=pos;x<arr.length; x++)

       {

           System.out.print(arr[x]+",");

   iv.     查表法十进制二进制

1.  原理同十进制向十六进制转换相同

2.  关键代码如下:

public static void toBin(int num)

{   //定义二进制的表。

       char[]chs = {'0','1'};

    //定义一个临时存储容器。

       char[]arr = new char[32];

    //定义一个操作数组的指针

       intpos = arr.length;

while(num!=0)

       {

           inttemp = num & 1;

           arr[--pos]= chs[temp];

           num= num >>> 1;

       }

for(int x=pos; x<arr.length; x++)

       {

           System.out.print(arr[x]);

     v.     查表法向十进制与二进制转换的优化

public static void main(String[] args)

    {

       toBin(-6);

       toHex(-60);

       toBa(60);

//  System.out.println(Integer.toBinaryString(6));

//  System.out.println(Integer.toHexString(6));

    }

//  十进制-->二进制

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,intbase,int offset)

{

    if(num==0)//判断特殊情况,如果是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];

       intpos = arr.length;

       while(num!=0)

       {

           inttemp = num & base;

           arr[--pos]= chs[temp];

           num= num >>> offset;

       }

       for(intx=pos; x<arr.length; x++)

       {

           System.out.print(arr[x]);

       }

       return;

    }

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值