-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
七、函数
1.什么是函数?
定义在类中的具有特定功能的一段独立小程序 ,就叫函数,也可以称为方法。
2.函数的格式:
修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,…)
{
执行语句;
return返回值;
}
其中:
返回值类型:函数运行后的结果的数据类型。
参数类型:是形式参数的数据类型。
形式参数:是一个变量,用于存储调用函数时传递给函数的实际参数。
实际参数:传递给形式参数的具体数值。
return:用于结束函数。
返回值:该值会返回给调用者。
3.函数特点:
1)定义函数可以将功能代码进行封装,便于对该功能进行复用。
2)函数只有被调用才会被执行。
3)函数的出现提高了代码的复用性。
4)对于函数没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写。
注意:
a) 函数中只能调用函数,不可以在函数内部定义函数。
b) 定义函数时,函数的结果应该返回给调用者,交由调用者处理。4.函数重载:
1)定义:在同一个类中,如果两个函数同名,那么参数列表的个数或者参数类型不同(包括参数的先后顺序)即为重载。
2)作用:方便于阅读,优化了程序设计。
3)重载示例:
- class Overload //函数重载
- {
- public static void main(String[] args)
- {
- System.out.println(get(2)+"-----"+get(1,3));
- }
- public static int get(int x)//定义一个函数,返回x的平方
- {
- return x*x;
- }
- public static int get(int a,int b)//定义一个函数,返回a+b的和
- {
- return a+b;
- }
- }
注:重载与返回值类型无关,同一个类中,如果两个函数返回值类型不同,而函数名、参数列表的个数和参数类型相同,那么是不允许同时存在的,因为调用时不能确定具体调用的对象。
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)内存分配:
数组引用数据类型,内存分配情况如下图:
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)排序:
排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存,主要排序方法有选择排序、冒泡排序、快速排序、希尔排序、堆排序、插入排序、归并排序等。
排序有很多方法可以实现,这里只对选择排序和冒泡排序进行介绍:
选择排序:
原理:在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。
代码示例:
- //选择排序
- public static void selectSort(int[] arr)
- {
- //定义一个临时变量
- int temp=0;
- //对arr数组进行遍历
- for (int x=0;x<arr.length ;x++ )
- {
- for (int y=x+1;y<arr.length ;y++ )
- {
- //将角标为x的值与之后的每一个元素进行比较,如果y角标的值比x角标的值打,将x和y的值互换
- if (arr[x]<arr[y])
- {
- temp=arr[x]; //将x角标的值赋给temp
- arr[x]=arr[y];//将y角标的值赋给x角标
- arr[y]=temp; //将temp的值赋给y角标
- }
- }
- }
- }
冒泡排序:
原理:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
代码示例:
- //冒泡排序
- public static void bubbleSort(int[] arr)
- {
- //定义临时变量
- int temp=0;
- //将arr数组进行遍历
- for (int x=arr.length;x>0 ;x-- )
- {
- for (int y=0;y<x-1 ;y++ )
- {
- //将角标为y的值与角标为(y+1)的值进行比较,如果y角标元素的值比(y+1)角标元素的值大,将两个元素的值互换
- if (arr[y]<arr[y+1])
- {
- temp=arr[y+1]; //将角标y+1元素的值赋给temp
- arr[y+1]=arr[y]; //将角标y元素的值赋给角标为y+1的元素
- arr[y]=temp; //将temp的值赋给角标为y的元素
- }
- }
- }
- }
2)查找:
对数组进行查找的方法主要介绍两种,即二分查找法和查表法。
二分查找法:
原理:定义两个指针start和end分别指向数组的最前和最后两个数,将start和end的角标值相加并除以2,并将该值用变量mid进行记录,如果数组mid角标的数值比要查找的值大,则把mid角标赋给end,反之赋给start,如果相等则停止查找,就这样不断重复循环该过程,直到start等于end,或者找到查找的值为止。
代码示例:
- //二分查找
- public static void halfSearch(int[] arr,int a)
- {
- //定义两个指针start和end分别指向arr数组的最前和最后两个数
- int start=0,end=arr.length-1;
- //定义一个变量mid和标志flag
- int flag=0,mid=0;
- //建立循环,只要指针start<=end就继续循环
- while (start<=end)
- {
- //将两个指针的角标值相加再除以2赋给mid
- mid=(start+end)/2;
- if (arr[mid]>a)
- //如果角标为mid的元素的值大于要查找的值,则将mid-1的赋给指正end
- end=mid-1;
- else if (arr[mid]<a)
- //如果角标为mid的元素的值小于要查找的值,则将mid-1的赋给指正end
- start=mid+1;
- else
- {
- //如果角标为mid的元素的值等于要查找的值,则将flag置为1
- flag=1;
- break;
- }
- }
- if (flag==1)
- //如果标志被置为1,则要查找的值的角标为mid
- System.out.println("要查找的数在数组的角标为:"+mid);
- else
- //如果标志flag为0,则数组中没有要查找的值
- System.out.println("要查找的数没有在该数组中找到!");
- }
查表法(进制转换):
原理:将所有元素临时存储起来,建立对应关系。每一次&进制的最大数后的值,作为索引去查建立好的表,就可以找对应的元素。
代码示例1:十进制转十六进制
- //十进制转十六进制
- public static void toHex(int num)
- {
- //通过char数组建立一个十六进制的表;
- char [] chs={'0','1','2','3','4','5','6',
- '7','8','9','A','B','C','D',
- 'E','F'};
- //定义一个StringBuffer容器;
- StringBuffer sb= new StringBuffer();
- //将数转换成十六进制,并存储到容器中;
- while(num!=0)
- {
- int temp=num&15;
- sb.append(chs[temp]);
- num=num>>>4;//无符号右移;
- }
- System.out.println(sb.reverse());//将容器的对象反序输出;
- }
代码示例2:十进制转二进制
- //十进制转二进制
- public static void toBin(int num)
- {
- //通过char数组建立二进制的表;
- char [] chs={'0','1'};
- char [] arr= new char[32];//建立一个临时存储二进制位数据的容器,对于int类型,只需长度为32即可;
- int pos=arr.length;
- //将数取余后,逐个存储到容器中;
- while (num!=0)
- {
- arr[--pos]=chs[num&1];//不建议用num%2的方法,因为负数%2之后得到的还是负数,将查表失败;
- num=num>>>1;//无符号右移4位;
- }
- //输出转换的二进制数;
- for (int x=pos;x<arr.length ;x++ )
- {
- System.out.print(arr[x]+"");
- }
- System.out.println();
- }
注:进制转换用查表法,可只建立一个表,完成多个进制的转换。