您的位置:首页 > 职场人生

黑马程序员——Java基础语法 之函数,数组

2015-10-21 23:16 579 查看
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

**

函数

**

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

定义函数格式

修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型,形式参数2…………){
执行语句;
return 返回值;
}


返回值类型:函数运行后的结果的数据类型,无参数返回写void。

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

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

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

return:用于结束函数,返回值类型为void时可以省略。

返回值:该函数运算后的结果,该结果会返回给调用者。

例子:

class TestDemo
{
public static void main(String[] args){
int c = add(3,4);
System.out.println("c = " + c);
}
public static int add(int a, int b){
return a + b;
}
}


函数特点

1,把功能封装,提高代码阅读性

2,方便代码复用,提高复用性

3,被调用才会执行

4,函数内部可以调用函数(包括调用自己本身的函数和别的函数),但不能在内部定义函数,自己调用自己叫递归

函数的应用

定义函数需明确几点:

1调用函数是否只有类内部调用,是可以用private修饰,否可以用public,或默认,需明确调用范围

2是否静态函数调用,是修饰符要加static,否就可以不加

3函数最后得出的结果是什么,是否需要返回结果,确定返回值类型

4在定义功能过程,是否需要未知内容参与运算,确定参数。

函数的重载:

在同一个类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可。

重载特点

1除了参数列表(包括参数个数或者参数类型),函数的修饰符必须相同,而返回值类型可同可不同。

2重载函数有利于阅读和优化程序设计。

例一

class TestDemo
{
public static void main(String[] args){
int a = 4;
double b =4.0;
float c=4.0f;
String d="4";
print(a);print(b);print(c);print(d);
}
public static void print(int x){
System.out.println("
4000
我是int类型"+x);
}
public static void print(double x){
System.out.println("我是double类型"+x);
}
public static void print(float x){
System.out.println("我是float类型"+x);
}
public static void print(String x){
System.out.println("我是String类型"+x);
}
}


例二

class  TestDemo
{
public static void main(String[] args)
{
printTable();//没有参数为默认99乘法表
printTable(7);//有参数则以参数为准

}
public static void printTable(){
printTable(9);
}

public static void printTable(int num){
for(int i=1;i<=num;i++){
for(int j=1;j<=i;j++){
System.out.print(j+"*"+i+"="+(i*j)+"\t");
}
System.out.println();
}
}
}


数组

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

把相同类型的数据作为元素有序排列放入数组,从0开始编号,方便操作这些元素

格式1:

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


格式2:需要一个容器,存储已知的具体数据。

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


例如

int[] arr = new int[5];
float arr[]=new float[5];
float arr[]=new float[]{2.1f,2.2f,2.6f};
double[] arr={5.0,6.3,8.2,1.52};
String[] arr=new String[]{"ef","2fc","12","5d"};
……


数组的内存分配及特点



内存的划分:

1.寄存器

2**.本地方法区**。

3.方法区

4.栈内存。用于存储局部变量,当变量所属的作用域一旦结束,所占空间会自动释放。

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

实体中的变量都有默认初始化值,根据类型的不同而不同。整数类型是0,小数类型是0.0或0.0f,boolean类

型是false,char类型是’\u0000’。

如果将数组的引用实体设置为null,也就是实体不再被使用,那么会在不确定的时间内被垃圾回收器回收。

数组应用常见错误:

错误一

int[] a;
a={1,5,7,89,}//必须在声明的同时初始化,注意,最后的‘,’不算错


错误二

int[] a =new int[];//必须声明数组长度int[] a =new int[4];


错误三:

int[] a =new int[5];
for(int i=0;i<=a.length;i++){
Sytem.out.print(a);//打印结果是数组a的内存地址的哈希值,而不是数组里面的元素
System.out.print(a[i]);//循环去到a[a.length]会报空指针异常
}


错误四,并不常见

int[] a=new int[-1];


编译可以通过,但运行时会产生NegativeArraySizeException异常。

数组的常见操作:存,取

通过对角标的操作选定数组元素进行存取

遍历并打印数组元素

class  TestDemo
{
public static void main(String[] args)
{
int[] arr=new int[]{1,5,6,8,7};
for(int i = 0;i<arr.length;i++){
System.out.print(arr[i]);
}
}
}


结果:

15687


求最值

练习:求数组中的元素的最大值

class  TestDemo
{
public static void main(String[] args)
{
int[] arr=new int[]{1,9,6,8,7};
int max=0;
for(int i = 0;i<arr.length;i++){
if(arr[max]<arr[i])
max=i;
}
System.out.print(arr[max]);
}
}


数组排序:

排序有两个逻辑方法,一个是选择排序,一个是冒泡排序

由小到大选择排序逻辑是,拿左边第一个位置的元素依次与右边每一个元素作比较,要是第一个元素比某个元素大就交换位置,一直比到最后一个元素,此时第一个元素就是最小的元素,然后第二个元素做相同动作,直到所有元素都进行比较完毕。

而另一个由小到大冒泡排序逻辑是,第一位置元素跟第二个位置元素比较,如果第一个位置元素大就交换位置,否则不变,然后第二个元素跟第三个元素比较,如果第二个元素大就交换位置,一直循环下去直到比完最后一个元素,得出最后一个元素为最大,为一轮,第二轮跟上面一样,第一个跟第二个比,第二个跟第三个比……直到倒数第二元素到下一轮,如此类推

例子:

class  SortDemo
{
public static void main(String[] args)
{
int[] arr=new int[]{5,9,7,6,3,5,1,2,4};
printArray(arr);
SelectSort(arr);
//SelectSort2(arr);
//bubbleSort(arr1);
//Arrays.sort(arr);//java api提供方法
printArray(arr);

}
//由于方法中参数arr传入都是数组的引用,所以等于直接操作数组
//而无需返回int数组
public static void SelectSort(int[] arr){//选择排序法
for(int i=0;i<arr.length;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
swap(arr,i,j);
}
}
}
}
public static void SelectSort2(int[] arr){//高效选择排序法
int minnum=arr[0];//记住最小值与最小值角标减小频繁读取数组的值
int min=0;
for(int i=0;i<arr.length;i++){
for(int j=i+1;j<arr.length;j++){
if(minnum>arr[j])
min=j;
minnum=arr[j];
}
if(i!=min)
swap(arr,i,min);
}
}
public static void bubbleSort(int[] arr){//冒泡排序法
for(int i=arr.length;i>0;i--){
for(int j=0;j<i-1;j++){
if(arr[j]>arr[j+1])
swap(arr,j,j+1);
}
}
}
public static void swap(int[] arr,int key1,int key2){//交换方法
arr[key1]=arr[key1]^arr[key2];
arr[key2]=arr[key1]^arr[key2];
arr[key1]=arr[key1]^arr[key2];
}
public static void printArray(int[] arr){//打印数组方法
for(int num:arr){
System.out.print(num+" ");
}
System.out.println();
}
}


数组查找

就是查找数组的元素

常用方法有遍历查找折半查找(又叫二分查找)

遍历方法:这个简单好理解,效率不高,不管有序无序都适用

int[] arr=new int[]{5,9,7,6,3,1,2,4};
int tagetIndex=0;
for(int i=0;i<arr.length;i++)
{
if(arr[i]==3)
{
System.out.println("找到3了");
tagetIndex=i;
}
}


折半查找,这个只适用于有序排列,较为高效

逻辑是把全部数组元素取中间值,然后目标值与中间值比较

如果中间值比目标值小,就以中间角标+1作为最小值与最大值角标组成新数组范围,再折半查找,直到找到目标或者最小值>=最大
c385
值,此时最小值为如果目标值存在时的应在位置

函数代码:

public static int halfSearch(int[] arr,int key){//要是找不到则返回-1
int min=0;
int max=arr.length-1;
int mid=(max+min)/2;
while(arr[mid]!=key){
if(arr[mid]>key){
max=mid-1;
}else{
min=mid+1;
}
if(max<min)
return -1;//要是把这里改为return min;这函数找不到会返回目标值存在时的应在位置
mid=(max+min)/2;
}
return mid;
}


java api也有折半查找函数

Arrays.binarySearch(arr,5);


第一个参数输入数组,第二个参数是关键字,找到就返回位置,找不到就返回应在位置的负数-1

api文档写的是(-接入点-1)

练习

求十进制整数的二进制,八进制,十六进制的表现形式

由之前笔记可知,八进制为整数的二进制的以三位为一组的数值组成,例如:

69二进制为001000101,每三位一组分割001-000-101,每三位表示的十进制数为1-0-5

所以其八进制表现形式为105

十六进制同理

69二进制为001000101,每四位一组分割0100-0101,每四位表示的十进制数为45

所以其十六进制表现形式为45

在逻辑运算思路为

十进制转八进制:69对7进行与操作,取其最低位三位的值,记录在数组,而后无符号右移三位再与,新值与7取值,记录,直到剩下的数为0

十进制转十六进制:69对15进行与操作,取其最低位四位的值,记录在数组,而后无符号右移右位再与,新值与15取值,记录,直到剩下的数为0

转二进制同理,与1,右移1位

代码:

class ArrayDemo
{
public static void main(String[] args)
{
toBin(9);
toOctal(9);
toHex(9);

}
public static void toBin(int x) //十转二
{
trans(x,1,1);
}
public static void toOctal(int x)//十转八
{
trans(x,7,3);
}
public static void toHex(int x) //十转十六
{
trans(x,15,4);
}
public static void trans(int num,int base,int offset){
StringBuilder str=new StringBuilder();
char[] chs=new char[]{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
char[] ch=new char[32/offset];
int len=0;
while(num!=0){
ch[len++] = chs[num & base];
num=num>>>offset;
}
for(int i=len-1;i>=0;i--){
str.append(ch[i]);
}
System.out.println(str);
}
}


同样,JDK也提供了API给调用

Integer.toHexString(60);


上面例子运用了数组常用的查表法,就是把特定字符定义在数组用,然后通过角标定位返回特定字符。

char[] chs=new char[]{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};


常见错误:

int[] x=new int[]{1,4,9,6,2};
int[] y=x;


注意这里不是把x引用int[5]对象复制给y,只是把x的引用赋值给y,对y操作等于对x操作

如:

y[0]=11;
x[0]=10;
System.out.print(“y[0]”+y[0]);结果为y[0]=10;


要复制数组,可以自己写for循环

也可以直接使用api提供的方法:

System.arraycopy(Object src,int srcPos,Object dest,int destPos,int length)


使用此方法需要捕捉或抛出异常

多维数组

二维数组[][],三位数组[][],四维数组[][]………………

格式:

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


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

2、二维数组中有3个一维数组。

3、每一个一维数组中有2个元素。

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

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

6、arr存储的是二维数组的初始地址,arr[0]、arr[1]、arr[2]存储的是一维数组的初始地址。

格式2:

int[][] arr=new int[3][]


定义了3个一维数组,每个一维数组都是默认初始值为null,可以对这三个一维数组分别初始化:

arr[0]=new int[3];
arr[1]=new int[4];
arr[2]=new int[5];


格式3:

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


声明定义同时直接赋值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java