黑马程序员——Java语法基础(二)

时间:2021-08-13 12:39:47

-----------android培训java培训、java学习型技术博客、期待与您交流!------------

七、函数

     1.什么是函数?

      定义在类中的具有特定功能的一段独立小程序 ,就叫函数,也可以称为方法。

     2.函数的格式:

                           修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,…) 

                         {

                           执行语句;

                            return返回值;

                         }

      其中:

              返回值类型:函数运行后的结果的数据类型。

              参数类型:是形式参数的数据类型。

              形式参数:是一个变量,用于存储调用函数时传递给函数的实际参数。

              实际参数:传递给形式参数的具体数值。

              return:用于结束函数。

             返回值:该值会返回给调用者。

      3.函数特点:

      1)定义函数可以将功能代码进行封装,便于对该功能进行复用。

      2)函数只有被调用才会被执行。

      3)函数的出现提高了代码的复用性。

      4)对于函数没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写。

      注意:

             a) 函数中只能调用函数,不可以在函数内部定义函数。

             b) 定义函数时,函数的结果应该返回给调用者,交由调用者处理。

      4.函数重载:

      1)定义:在同一个类中,如果两个函数同名,那么参数列表的个数或者参数类型不同(包括参数的先后顺序)即为重载。

      2)作用:方便于阅读,优化了程序设计。

      3)重载示例:  

[java] view plaincopy
  1. class Overload //函数重载   
  2. {  
  3.     public static void main(String[] args)   
  4.     {  
  5.         System.out.println(get(2)+"-----"+get(1,3));  
  6.     }  
  7.     public static int get(int x)//定义一个函数,返回x的平方  
  8.     {  
  9.         return x*x;  
  10.     }  
  11.     public static int get(int a,int b)//定义一个函数,返回a+b的和  
  12.     {  
  13.         return a+b;  
  14.     }  
  15. }  
        上面自定义的两个函数发生了重载,因为函数名一样,但参数列表不同。

      注:重载与返回值类型无关,同一个类中,如果两个函数返回值类型不同,而函数名、参数列表的个数和参数类型相同,那么是不允许同时存在的,因为调用时不能确定具体调用的对象。

      4)重载的应用场合:

      当定义的功能相同,但参与运算的未知内容不同,可通过重载实现。

      5.问题思考

     函数定义名称是为什么?有什么作用?

     ——可以让人见名知意,方便于调用,增加代码的阅读性。


八、数组

    1.什么是数组?

     同一种类型数据的集合,就成为数组。

     2.一维数组:

     1)定义:一维数组是由数字组成的以单纯的排序结构排列的结构单一的数组。

     2)格式:格式有两种。

     格式1:元素类型 [ ]   数组名 = new 元素类型 [元素个数或数组长度] 

     示例: int [ ]  arr = new int [3]

     格式2:元素类型 [ ]   数组名 = new 元素类型 [ ]{元素1,元素2,…}

     示例:int [ ]  arr = new int [ ]{1,2,3,4,5}

     静态初始化格式:元素类型 [ ]   数组名 = {元素1,元素2,…}

     示例:int [ ] arr={1,2,3,4,5}

     注:new是用来在堆内存中产生一个容器实体。

     3)内存分配:

     数组引用数据类型,内存分配情况如下图:

     黑马程序员——Java语法基础(二)

     3.二维数组:

     1)定义:一个一维数组存放的元素为一维数组时,该数组即为二维数组。

     2)格式:主要有3种。

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

     格式2示例: int[ ][ ] arr= new int[3][ ]

     格式3示例:int[ ][ ] arr = {{3,8,2},{2,7},{9,0,1,6}}

     注:此种格式中每个一维数组都是默认初始化值null,一种特殊定义写法:int[ ]   x,y[ ]; x是一维数组,y是二维数组。

     4.数组常识:

     1)使用输出语句直接打印数组,如System.out.println(arr),得到的结果是一个哈希值,也叫地址值。

     2)数组在堆内存开辟空间后,就有默认的初始化值。如:int默认0;boolean默认false;double默认是0.0;float默认是0.0;string默认为null。

     3)为了提高程序运算效率,java对内存空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。主要介绍栈内存和堆内存的特点:

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

     堆内存:  

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

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

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

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

     4)两个常见异常:角标越界异常(ArrayIndexOutOfBoundsException)和空指针异常(NullPointerException)

     角标越界异常:访问到了数组中的不存在的脚标时发生。

     空指针异常:引用没有指向null,却在操作实体中的元素。

     注:通过new进行初始化数组时,在编译时期数组对象还没建立,因此数组角标越界异常(ArrayIndexOutOfBoundsException)和空指针异常(NullPointerException)只在运行时期产生。

     5)获取数组长度:

     获取数组arr的长度为arr.length()方法获取,如果arr为二维数组,那么arr.length()获取的是一维数组的个数,如果数组元素arr[x]还是一个数组时,可通过arr[x].length()获取其内元素的个数,即arr[x]的长度。

     5.数组常见操作:

     1)排序:

     排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存,主要排序方法有选择排序、冒泡排序、快速排序、希尔排序、堆排序、插入排序、归并排序等。

     黑马程序员——Java语法基础(二)

      

     排序有很多方法可以实现,这里只对选择排序和冒泡排序进行介绍:

     选择排序:

     原理:在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。

     代码示例:

[java] view plaincopy
  1. //选择排序  
  2. public static void selectSort(int[] arr)  
  3. {   
  4.     //定义一个临时变量  
  5.     int temp=0;  
  6.     //对arr数组进行遍历  
  7.     for (int x=0;x<arr.length ;x++ )  
  8.     {  
  9.         for (int y=x+1;y<arr.length ;y++ )  
  10.         {  
  11.             //将角标为x的值与之后的每一个元素进行比较,如果y角标的值比x角标的值打,将x和y的值互换  
  12.             if (arr[x]<arr[y])  
  13.             {  
  14.                 temp=arr[x]; //将x角标的值赋给temp  
  15.                 arr[x]=arr[y];//将y角标的值赋给x角标  
  16.                 arr[y]=temp; //将temp的值赋给y角标  
  17.             }  
  18.         }  
  19.     }  
  20. }  
 

      冒泡排序:

     原理:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。

     代码示例:

[java] view plaincopy
  1.        //冒泡排序  
  2. public static void bubbleSort(int[] arr)  
  3. {  
  4.     //定义临时变量  
  5.     int temp=0;  
  6.     //将arr数组进行遍历  
  7.     for (int x=arr.length;x>0 ;x-- )  
  8.     {  
  9.         for (int y=0;y<x-1 ;y++ )  
  10.         {  
  11.             //将角标为y的值与角标为(y+1)的值进行比较,如果y角标元素的值比(y+1)角标元素的值大,将两个元素的值互换  
  12.             if (arr[y]<arr[y+1])  
  13.             {  
  14.                 temp=arr[y+1]; //将角标y+1元素的值赋给temp  
  15.                 arr[y+1]=arr[y]; //将角标y元素的值赋给角标为y+1的元素  
  16.                 arr[y]=temp; //将temp的值赋给角标为y的元素  
  17.             }  
  18.         }  
  19.     }  
  20. }  

     2)查找:

     对数组进行查找的方法主要介绍两种,即二分查找法和查表法。

     二分查找法:

     原理:定义两个指针start和end分别指向数组的最前和最后两个数,将start和end的角标值相加并除以2,并将该值用变量mid进行记录,如果数组mid角标的数值比要查找的值大,则把mid角标赋给end,反之赋给start,如果相等则停止查找,就这样不断重复循环该过程,直到start等于end,或者找到查找的值为止。

     代码示例:   

[java] view plaincopy
  1.                     //二分查找  
  2. public static void halfSearch(int[] arr,int a)  
  3. {  
  4.     //定义两个指针start和end分别指向arr数组的最前和最后两个数  
  5.     int start=0,end=arr.length-1;  
  6.     //定义一个变量mid和标志flag  
  7.     int flag=0,mid=0;  
  8.     //建立循环,只要指针start<=end就继续循环  
  9.     while (start<=end)  
  10.     {  
  11.         //将两个指针的角标值相加再除以2赋给mid  
  12.         mid=(start+end)/2;  
  13.         if (arr[mid]>a)  
  14.             //如果角标为mid的元素的值大于要查找的值,则将mid-1的赋给指正end  
  15.             end=mid-1;  
  16.         else if (arr[mid]<a)  
  17.             //如果角标为mid的元素的值小于要查找的值,则将mid-1的赋给指正end  
  18.             start=mid+1;  
  19.         else  
  20.         {  
  21.             //如果角标为mid的元素的值等于要查找的值,则将flag置为1  
  22.             flag=1;  
  23.             break;  
  24.         }  
  25.     }  
  26.     if (flag==1)  
  27.         //如果标志被置为1,则要查找的值的角标为mid  
  28.         System.out.println("要查找的数在数组的角标为:"+mid);  
  29.     else  
  30.         //如果标志flag为0,则数组中没有要查找的值  
  31.         System.out.println("要查找的数没有在该数组中找到!");  
  32. }  

      查表法(进制转换):

      原理:将所有元素临时存储起来,建立对应关系。每一次&进制的最大数后的值,作为索引去查建立好的表,就可以找对应的元素。

      代码示例1:十进制转十六进制

[java] view plaincopy
  1.       //十进制转十六进制  
  2. public static void toHex(int num)  
  3. {  
  4.     //通过char数组建立一个十六进制的表;  
  5.     char [] chs={'0','1','2','3','4','5','6',  
  6.                  '7','8','9','A','B','C','D',  
  7.                  'E','F'};  
  8.     //定义一个StringBuffer容器;  
  9.     StringBuffer sb= new StringBuffer();  
  10.     //将数转换成十六进制,并存储到容器中;  
  11.     while(num!=0)  
  12.     {  
  13.         int temp=num&15;  
  14.         sb.append(chs[temp]);  
  15.         num=num>>>4;//无符号右移;  
  16.     }  
  17.     System.out.println(sb.reverse());//将容器的对象反序输出;  
  18. }  

      代码示例2:十进制转二进制 

[java] view plaincopy
  1.       //十进制转二进制  
  2. public static void toBin(int num)  
  3. {  
  4.     //通过char数组建立二进制的表;  
  5.     char [] chs={'0','1'};  
  6.   
  7.     char [] arr= new char[32];//建立一个临时存储二进制位数据的容器,对于int类型,只需长度为32即可;  
  8.       
  9.     int pos=arr.length;  
  10.       
  11.     //将数取余后,逐个存储到容器中;  
  12.     while (num!=0)  
  13.     {  
  14.         arr[--pos]=chs[num&1];//不建议用num%2的方法,因为负数%2之后得到的还是负数,将查表失败;  
  15.         num=num>>>1;//无符号右移4位;  
  16.     }  
  17.   
  18.     //输出转换的二进制数;  
  19.     for (int x=pos;x<arr.length ;x++ )  
  20.     {  
  21.         System.out.print(arr[x]+"");  
  22.     }  
  23.     System.out.println();  
  24. }  

     注:进制转换用查表法,可只建立一个表,完成多个进制的转换。