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

——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("我是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=0for(int i=0;i<arr.length;i++)
{
    if(arr[i]==3)
    {
        System.out.println("找到3了");
        tagetIndex=i;
    }
}

折半查找,这个只适用于有序排列,较为高效
逻辑是把全部数组元素取中间值,然后目标值与中间值比较
如果中间值比目标值小,就以中间角标+1作为最小值与最大值角标组成新数组范围,再折半查找,直到找到目标或者最小值>=最大值,此时最小值为如果目标值存在时的应在位置
函数代码:

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

声明定义同时直接赋值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值