天天看点

黑马程序员——Java基础笔记---数组

------<a href="http://www.itheima.com" target="_blank" rel="external nofollow" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

A、基本概念

定义:同一个类型数据的集合,其实数组就是一个容器。

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

格式1:

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

示例:int [ ]arr = new int[3 ]也可以写成:int arr [] = new int[3 ],但一般都按规范来写。

定义一个可以存储3个整数的容器。

int [ ]x = new int[ 3 ];

格式2:

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

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

也可简化为:int [ ]arr = { 3,5,1,7 };

B、内存结构

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

   栈内存:用于存储局部变量,当数据使用完毕后,所占的空间会被自动释放。

   堆内存:

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

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

   *实体中的变量都有默认的初始化值(例int:0;boolean:false;double:0.0)

   *实体不在被使用,会在不确定的使劲按内被垃圾回收器回收

 另:除了以上两个内存区外,还有方法区、本地方法区、寄存器

实例:

classArrayDemo

{

public static void main(String[] args)

{

    int[] arr = new int[3];

   arr=null;

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

}

}

在没有arr=null;运行时给出错误提示:

Array indexout of bounds exception:3:操作数组时,访问到了数组中不存在的角标。

在有arr=null;运行时给出错误提示:

Null pointerexception:空指针异常,当引用没有任何指向值为null的情况,该引用还在用语操作实体。

C 1、数组的常见操作——遍历

获取数组中的元素,通常会用到遍历

classArrayDemo2

{

public static void main(String[] args)

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

{

    int[] arr = new int[]{ 3,6,5,1,8,9,67};

    System.out.println(“arr[“+x+”]=”+arr[x]+”;”);

}

}

总结:数组中有一个属性可以直接获取到数组元素的个数:length

     使用方式:”数组名称.length”

上面的程序在或许打印元素的取值范围时就有用到。

练习:用于打印数组中的元素int[]arr={ 3,6,5,1,8,9,67};,元素间用逗号隔开

classArrayDemo2

{

public static void main(String[] args)

{

   int[]arr={ 3,6,5,1,8,9,67}

printArray(arr);

}

public static void printArray([ ]arr)

{

    System.out.print(“[”)

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

{

   if(x!=arr.length-1)

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

else

System.out.println(arr[x] + ”]”);

      }

}

}

注:再打印数组时,如果直接用“System.out.print(arr)”来进行打印,那么得到的会是该数组空间的16进制的内存地址值。

练习题:

给定一个数组{5,1,6,4,2,8,9}

1、 获取该数组中的最大值和最小值。

思路:

a、获取最值需要进行比较,每一次比较都会有一个较大的值,因为该值不确定,通过一个变量进行临时存储。

b、让数组中的每一个元素都和这个变量中的值进行比较,如果大于了变量中的值,就用该变量记录较大值。

c、当所有的元素都比较完成,那么该变量中储存的值就是数组中的最大值了

步骤:

a、  定义变量,初始化数组中的任意一个元素即可,

b、  通过循环语句对数组进行遍历

c、  在变量过程中定义判断条件,如果遍历到的元素比变量中的元素大,就赋值给该变量:

需要定义一个功能来完成,以便提高复用性。

a、  明确结果,数组中的最大元素 int类型

b、  未知内容:一个数组,int[ ]

publicstatic int getMax(int[ ] arr)

{

   int max=arr[ 0 ];

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

   {

      if(arr[x]>max)

         max = arr[ x ];

}

returnmax;

}

publicstatic void main(String[ ] args)

{

   int[ ] arr={5,1,6,4,2,8,9}};

   int max = getMax(arr);

   System.out.println(“max=”+max);

}

获取最大值的另外一种方式。

可不可以将临时变量max初始化为0呢?可以,这种方式,其实是在初始化为数组中任意一个角标。

及:

publicstatic int getMax(int[ ] arr)

{

   int max= 0;

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

   {

      if(arr[x]>arr[max])

         max = x ;

}

returnarr [max] ;

}

publicstatic void main(String[ ] args)

{

   int[ ] arr={5,1,6,4,2,8,9}};

   int max = getMax(arr);

   System.out.println(“max=”+max);

}

获取最小值:(同理)

publicstatic int getMin(int[ ] arr)

{

   int min =0

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

   {

      if(arr[x]<arr[min])

         min=x;

   }

returnarr[min];

   }

publicstatic void main(String[ ] args)

{

   int[ ] arr={5,1,6,4,2,8,9}};

   int max = getMax(arr);

   int min = getMin(arr)

   System.out.println(“max=”+max);

   System.out.println(“min=”+min);

}

C2、数组的常见操作——排序

Array.sort(arr);  ——java中已经定义好的一种排序方式,开发中,对数组排序,要使用该句代码!

a、选择排序

实例:对数组{5,1,6,4,2,8,9}进行排序。

class ArrayTest1

{

   publicstatic void selectsort (int[] arr)

   {

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

      {

        for(inty=x+1; y<arr.length; y++)

        {

           if(arr[x]>arr[y])

           {

              inttemp=arr[x];

              arr[x]=arr[y];

              arr[y]=temp;

           }

        }

      } 

   }

   publicstatic void main(String[] args)

   {

      int[]arr={5,1,6,4,2,8,9};

      printArray(arr);

      selectsort(arr);

      printArray(arr);

   }

   publicstatic void printArray(int[]arr)

   {

      System.out.print("[");

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

      {

        if(x!=arr.length-1)

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

        else

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

      }

   }

}

总结:内循环结束一次,最值出现在头角标位置上

b、冒泡排序

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

特点:第一圈排序后,最值出现了最后位。    

class BubbleSort

{

   publicstatic void bubbleSort(int[] arr)

   {

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

      {

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

        {

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

           {

              inttemp=arr[y];

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

              arr[y+1]=temp;

           }

        }

      }

   }

   publicstatic void printArray(int[]arr)

   {

      System.out.print("[");

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

      {

        if(x!=arr.length-1)

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

        else

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

      }

   }

   publicstatic void main(String[] args)

   {

      int[]arr={5,1,6,4,2,8,9};

      printArray(arr);

      bubbleSort(arr);

      printArray(arr);

   }

}

c、排序——换位置功能的提取

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

public static void swap(int[] arr,int a,int b)

   {

      inttemp=arr[a];

      arr[a]=arr[b];

      arr[b]=temp;

   }

在上面b中的程序中,可以直接运行swap(arr);

D、数组——查找

定义功能,获取key第一次出现在数组中的位置,如果返回是 -1,那么代表该key值在数组中不存在

 实例:

class Index

{

   publicstatic void main(String[] args)

   {

      int[]arr={3,1,5,4,2,9};

      intindex=getIndex(arr,2);

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

   }

   publicstatic int getIndex(int[]arr,int key)

   {

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

      {

        if(arr[x]==key)

        {

           returnx;

        }

      }

      return-1;

   }

}

所以,如果在上面的程序的arr数组中出现了两个2,那么index输出的将是第一次2出现的角标值

折半查找

可以提高效率,但是必须要保证该数组是有序的数组。

classHalfSearch

{

   public static int halfSearch(int[] arr,intkey)

   {

      int min,mid,max;

      min=0;

      max=arr.length-1;

      mid=(max+min)/2;

      while ( arr[mid]!=key)

      {

        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 void main(String[] args)

   {

      int[] arr={2,4,5,7,19,32,45};

      int index=halfSearch(arr,55);

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

   }

}

折半的第二种方式:

classHalfSearch2 

{

   public static int halfSearch_2(int[]arr,intkey)

   {

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

      while (min<=max)

      {

        mid=(min+max)>>1;//等价于mid=(max+min)/2

        if (key>arr[mid])

           min=mid+1;

        else if (key<arr[mid])

           max=mid-1;

        else

           return mid;

      }

      return -1;

   } 

   public static void main(String[] args)

   {

      int[] arr={2,4,5,7,19,32,45};

      int index=halfSearch_2(arr,55);

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

   }

}

练习题1:有一个有序的数组,想要将一个元素插入到该数组中,还要保证数组是有序的,如何获取该元素在数组中的位置 {2,4,5,7,19,32,45}

classHalfPractice

{

publicstatic int halfSearch_2(int[]arr,int key)

   {

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

      while (min<=max)

      {

        mid=(min+max)>>1;

         if(key>arr[mid])

           min=mid+1;

        else if (key<arr[mid])

           max=mid-1;

        else

           return mid;

      }

      return min;

   } 

   public static void main(String[] args)

   {

      int[] arr={2,4,5,7,19,32,45};

      int index=halfSearch_2(arr,8);

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

    }

}

就是在最后返回时将halfSearch2中的return-1改成了return min,此时的min就是8应该所在的位置!

练习题2:十进制转二进制

classArrayTests

{

   public static void tobin(int num)

   {

      while (num>0)

      {

        System.out.print(num%2);

        num=num/2;

      }

   }

   public static void main(String[] args)

   {

      tobin(6);

   }

}

最后的输出结果是011,将显示的结果反过来就是110就是6的2进制数!

练习题3:十进制转十六进制

      class ArrayTest16

{

   public static void toHex(int num)

   {

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

      {

        int temp=num&15;

        if (temp>9)

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

        else

           System.out.println(temp);

        num= num>>> 4;

      }

   }

   public static void main(String[] args)

   {

      toHex(60);

   }

}

查表法:十进制转十六进制

将所有的元素临时存储起来,建立对应关系,每一次&15的值都作为引索去查建立好的表,就可以找对应得元素。这比-10+‘a’简单的多

这个表可以通过数组的形式来定义。

分析:

0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F——十六进制

0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15——角标

classChecktoHex

{

   public static void main(String[] args)

   {

      toHex(60);

   }

publicstatic void toHex(int num)

   {

      char[] chs={'0','1','2','3',

              '4','5','6','7',

              '8','9','A','B',

              'C','D','E','F'};

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

      {

   int temp=num&15;

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

   num=num>>>4;

}

   }

发现终于出结果了,但是结果是反着的,想要正过来,可以通过StringBufferreverse功能来完成,但是这个工具还没有学习,所以可以使用已经学过的容器,数组来完成反转存储 

classChecktoHex

{

   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)

      {

        int temp=num & 15;

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

        num = num >>> 4;

      }

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

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

      {

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

      }

   }

   public static void main(String[] args)

   {

      toHex(60);

   }

}

同理:编写十转二的查表法程序

class  ChecktoBin

{

   public static void toBin(int num)

   {

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

      char[] arr=new char [32];

      int pos=arr.length;

      while (num!=0)

      {

        int temp=num & 1;

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

        num = num >>> 1;

      }

      //System.out.println("pos="+pos);

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

      {

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

      }

   }

   public static void main(String[] args)

   {

      toBin(-6);

   }

}

由于通过查表法转二进制和十六进制有很多的相似之处,所以,我们可以从里面提取出一些共同的部分定义其功能!

classTranslation

{

  if(num==0)

  {

     System.out.println(0);

     return;

  }

  public static void main(String[] args)

  {

     toOct(32);

  }

  public static void toBin(int num)

  {

     trans(num,1,1);

  }

  public static void toOct(int num)

  {

     trans(num,7,3);

  }

  public static void toHex(int num)

  {

     trans(num,15,4);

  }

  public static void trans(int num,int base,intoffset)

  {

     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)

     {

        int temp=num&base;

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

        num=num>>>offset;

     }

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

     {

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

     }

  }

}

F、数组中的数组

——二维数组

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

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

l  二维数组中有3个一维数组

l  每一个以为数组中有两个元素

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

l  给第一个一维数组中角标为1的位赋值78,写法是:arr[0][1]=78;

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

l  二维数组中都是3个一维数组

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

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

l  int[ ] [] arr = new int[3][ ];

arr[0]=new int[3];

arr[1]=new int[1];

arr[2]=new int[2];

System.out.println(arr.length);//打印的是二维数组的长度

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

格式3:int[][]arr={{3,5,1,7},{2,3,5,7},{6,1,8,2}}

理解应用,如果上面数组表示一个公司三个销售团队每个季度的销售额度,那么求该公司一年的总销售额度?

分析:把所有的数都要加一边,所以要遍历,先遍历二维数组,再遍历二维数组中一维数组的每一个元素,所以有:

class PlanarArray

{

   publicstatic void main(String[] args)

   {

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

      intsum=0;

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

      {

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

        {

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

        }

      }

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

   }

}

补充知识:

一维数组的表现形式:

int[] x; int x[];————两种

int[][]y; int[] y[]; int y[][];————三种

练习:给出数组int[]x,y[];请问下面那一个是正确的?

分析:

int[] x,y[];——这个表达式等价于:

int[] x;int [] y[];

a.     x[0]=y;        error

b.     y[0]=x;        yes

c.     y[0][0]=x;     error

d.     x[0][0]=y;     error

e.     y[0][0]=x[0];  yes

f.     x=y            error

Summary: []定义在类型当中[]是跟着类型走的,在类型当中[]对他们都有效,而[]跟着字母走那么只对单个字母有效!