《Java开发实战经典》4 数组和方法

个人笔记,仅供参考,转载请注明出处,谢谢

目录

4.1 数组的定义和使用
  4.1.1 一维数组
  4.1.2 数组中元素的表示方法
  4.1.3 数组静态初始化
  4.1.4 数组应用范例
  4.1.5 二维数组
  4.1.6 多维数组
4.2 方法的声明和使用
  4.2.1 方法的定义
  4.2.2 方法的重载
  4.2.3 使用return结束一个方法
  4.2.4 方法的递归调用
4.3 数组的引用传递
  4.3.1 传递和返回数组
  4.3.2 示例:数组排序
4.4 Java新特性对数组的支持
  4.4.1 可变参数
  4.4.2 foreach输出

4.1 数组的定义和使用

4.1.1 一维数组

  • 存放一组数据,且类型相同
  • 使用数组的步骤
    1. 声明数组
    2. 分配内存给数组
1 声明数组分两种,没有区别:
数据类型 数组名[] = null;
或 数据类型 []数组名 = null;

2 数组名 = new 数据类型[长度]
  • 由于只有一个[]因此也称为一维数组
  • 数据类型是数组元素的数据类型,常见的有字符型、浮点型等
    数组名就是给这个数组命名的名称,规则和变量相同,建议使用有意义的名称
    数组声明以后,会在栈内存中保存数组的名称
  • 接着需要在堆内存中给这个数组分配内存
    长度是告诉编译器需要分配多少个元素
    new则是命令编译器根据长度在堆内存中开辟一块内存空间供这个数组使用

示例:

int score[] = null;
  • 声明了一个整型数组score,这个变量暂时没有包含任何内容
    编译器会在栈内存中分配一块内存给它
    用来保存指向数组实体地址的名称

问:为什么声明时要赋值为null?
答:null表示引用数据类型的默认值,表示暂时没有指向的内存空间

score = new int[3];
  • 声明之后,进行了堆内存分配
    开辟了3个可以保存整数的内存空间
    并把内存空间的参考地址赋值给了score变量
    《Java开发实战经典》4 数组和方法_第1张图片
  • 因为数组是引用数据类型,所以数组变量score保存的并非数组的实体
    而是数组堆内存的参考地址

栈内存和堆内存的解释

  • 数组操作中
    栈内存保存的是数组的名称,只开辟了栈内存的数组是无法使用的,必须开辟堆内存空间才可以使用
  • 想要开辟堆内存空间必须使用关键字new
    然后是将此堆内存的使用权交给了对应的栈内存空间
  • 而且一个堆内存空间
    可以被多个栈内存空间指向
    简单理解就是,类似一个人(堆)可以有多个名字(栈)

此外,可以把声明数组和分配内存合并在一起用较简洁的写法表示

  • 如:
int score[] = new int[3];

4.1.2 数组中元素的表示方法

  • 访问数组元素需要用索引的方法
    规律是从0开始作为第一个元素
    采用数组名称[下标]的方式
  • 整型数组,在没赋值的情况下,元素默认值为0
score[0] = 0; 代表第一个元素
score[1] = 0; 代表第二个元素
  • 示例:给数组元素赋值并输出
public class TestDemo {
    public static void main(String[] args) {
        int score[] = null;
        score = new int[3];
        for(int x=0; x<3 ; x++){
            score[x] = x*2+1;
        }
        for(int x=0; x<3 ; x++){
            System.out.println(score[x]);
        }
    }
}

运行结果:
1
3
5

可以看到已经给每个元素在堆内存中重新进行了赋值
《Java开发实战经典》4 数组和方法_第2张图片

获取数组的长度可以用数组名称.length来获得

public class TestDemo {
    public static void main(String[] args) {
        int score[] = new int[3];
        System.out.println(score.length);
    }
}

运行结果:
3

4.1.3 数组静态初始化

  • 之前的先声明后赋值属于动态初始化
    静态初始化则是直接在声明后面接花括号,并指明具体内容,元素之间用逗号分隔
  • 如:
int score[] = {1,2,3,4,5};

此时

score[0] 的值为1
score[1] 的值为2
以此类推......

4.1.4 数组应用范例

示例一:求最大值和最小值

public class TestDemo {
    public static void main(String[] args) {
        int score[] = {3,2,1,6,5,4,9,8,7,10};
        int max = 0;
        int min = 0;
        max = min = score[0];
        for(int x=0; xmax){
                max = score[x];
            }
            if(score[x]
  • 诀窍在于:
    先设置最大值和最小值默认为第一个元素
    再循环逐个与数组元素进行比较
    若大于最大值,则互换数值,保持max永远最大
    若小于最小值,则互换数值,保持min永远最小
    最终得到结果

示例二:数组从小到大进行排序

public class TestDemo {
    public static void main(String[] args) {
        int score[] = {3,2,1,6,5,4,9,8,7,10};

        for(int i=1; i < score.length; i++){
            for(int j=0; j < score.length; j++){
                if(score[i] < score[j]){
                    int temp = score[i];
                    score[i] = score[j];
                    score[j] = temp;
                }
            }
        }

        for(int i=0; i< score.length; i++){
            System.out.println(score[i]+" ");
        }
    }
}

运行结果:
1 2 3 4 5 6 7 8 9 10
  • 上面的例子用到了冒泡排序算法
    诀窍在于:
    双重循环来比较每一个元素,如果发现第i个元素大于i+1个元素
    就交换两者的位置
    这样就保证了每一次循环都能把最小的放在前面
    当所有循环结束,则比较结束

4.1.5 二维数组

  • 用法
int score[][];
score = new int[4][3];
  • 比较好理解的方法是把它看成是一个4行三列的表格
    那么一共可以保存12个元素
    《Java开发实战经典》4 数组和方法_第3张图片

示例一:二维数组用法

public class TestDemo {
    public static void main(String[] args) {
        int score[][] = new int[4][3];
        score[0][1] = 30;
        score[1][0] = 31;
        score[2][2] = 32;
        score[3][1] = 33;
        score[1][1] = 30;
        for(int i=0; i< score.length; i++){
            for(int j=0; j
  • 可以发现一些规律
    一维数组如果要全部输出,则需要一层循环
    二维数组如果要全部输出,则需要二层循环
    同理,N 维数组全部输出,需要 N 层循环

示例二:二维数组静态初始化

public class TestDemo {
    public static void main(String[] args) {
        int score[][] = { {67,61},{78,89,83},{99,100,98,66,95} };
        for(int i=0; i< score.length; i++){
            for(int j=0; j

4.1.6 多维数组

  • 这里不赘述了
  • 不难发现规律
    有多少个[]就代表几维数组
    如四维数组就是 int score[][][][]
    N维数组输出,就需要N层循环来打印

4.2 方法的声明和使用

4.2.1 方法的定义

  • 方法就是一段可以重复调用的代码块
  • 方法有的也称函数
  • 方法定义的格式为:
public static 返回值类型 方法名(类型 参数1,类型 参数2,......){
  程序语句;
  [return 表达式]
}
  • 要注意的是:
    如果不需要传参数到方法中,括号内可以不填入任何内容
    如果方法没有返回值,返回值类型记得写成void,且return可以省略
    方法执行完后,无论是否存在返回值都将返回方法的调用处并向下继续执行

示例一:定义方法,在主方法中调用

public class TestDemo {
    public static void main(String[] args) {
        printInfo();
    }

    public static void printInfo(){
        System.out.println("我是printInfo方法");
    }
}

运行结果:
我是printInfo方法
  • 由于printInfo方法本身没有返回值,因为返回值类型写成了void,且无需return语句
  • 方法的命名规则要求:第一个单词全小写,第二个单词以后首字母大写

示例二:带返回值的方法

public class TestDemo {
    public static void main(String[] args) {
        int one = addOne(1);
        System.out.println(one);
    }

    public static int addOne(int num){
        return num+1;
    }
}

运行结果:
2

4.2.2 方法的重载

  • 关键在于方法名称相同,参数类型和参数个数不同
public class TestDemo {
    public static void main(String[] args) {
        int one = add(10,10);
        int two = add(10,20,30);
        float three = add(10.3f,13.3f);
        System.out.println(one);
        System.out.println(two);
        System.out.println(three);
    }

    public static int add(int x, int y){
        return x+y;
    }
    public static int add(int x, int y, int z){
        return x+y+z;
    }
    public static float add(float x, float y){
        return x+y;
    }
}

运行结果:
20
60
23.6
  • 可以看到add方法被重载了3次
    第二次是参数个数不同
    第三次是参数类型不同
  • 其实,System.out.println()也属于重载方法,输出各种结果
System.out.println(3);
System.out.println(3.6f);
System.out.println('3');
System.out.println(true);
System.out.println("hello");
  • 需要注意,牢记重载只与参数类型和个数有关
    返回值类型无关
    public static int add(int x, int y){
        return x+y;
    }
    public static float add(int x, int y){
        return (float)x+y;
    }
  • 这里的add方法就不是重载

4.2.3 使用return结束一个方法

  • 在Java的方法定义中,可以使用return直接结束方法
public class TestDemo {
    public static void main(String[] args) {
        System.out.println("我是语句一");
        fun(10);
        System.out.println("我是语句四");
    }

    public static void fun(int x){
        System.out.println("我是语句二");
        if(x==10){
            return;
        }
        System.out.println("我是语句三");
    }
}

运行结果:
我是语句一
我是语句二
我是语句四
  • 可以看到只要调用了return
    方法将不再继续执行,而是返回到被调用处继续向下执行

4.2.4 方法的递归调用

  • 递归调用就是自己调用自己

示例一:完成累加操作

public class TestDemo {
    public static void main(String[] args) {
        System.out.println("累加结果:"+sum(100));

    }

    public static int sum(int num){
        if(num==1){
           return 1;
        }else {
            return num + sum(num-1);
        }
    }
}

运行结果:
累加结果:5050
  • 不推荐使用递归,如果处理不好,容易出现内存溢出

4.3 数组的引用传递

4.3.1 传递和返回数组

  • 前面的操作传递和返回都是基本数据类型
    方法中也可以用来传递和返回数组
    如果要向方法传递一个数组,则方法接收参数必须是符合其类型的数组
    而且数组属于引用数据类型
    把数组传递进方法以后,如果方法本身对数组做了任何修改
    修改结果也将保存下来

示例一:传递数组

public class TestDemo {
    public static void main(String[] args) {
        int temp[] = {1,3,5};
        fun(temp);
        for(int i=0; i< temp.length; i++){
            System.out.println(temp[i]+" ");
        }
    }

    public static void fun(int x[]){
        x[0] = 6;
    }
}

运行结果:
6 3 5

《Java开发实战经典》4 数组和方法_第4张图片

  • 分析:
    一开始声明的数组内容为 1 3 5
    但是将此数组传递到了方法中,用数组x来进行接收
    也就是说事实上temp数组是将堆内存的使用权传递给了方法
    数组x也指向了这些堆内存的内容
    因此可以进行修改
    方法执行完毕以后
    由于x属于局部变量所以就失效了
    但是对于数组内容的改变却保留了下来
    这个过程就是数组引用传递的过程

4.3.2 示例:数组排序

  • 用冒泡排序
public class TestDemo {
    public static void main(String[] args) {
        int score[] = {67,89,87,69,90,100,75,90};
        int age[] = {31,30,18,17,8,9,1,39};
        sort(score);
        print(score);
        sort(age);
        print(age);
    }

    public static void sort(int temp[]){
        for(int i=1; i
  • 使用Java类库java.util.Arrays.sort(score)
public class TestDemo {
    public static void main(String[] args) {
        int score[] = {67,89,87,69,90,100,75,90};
        int age[] = {31,30,18,17,8,9,1,39};
        java.util.Arrays.sort(score);
        print(score);
        java.util.Arrays.sort(age);
        print(age);
    }
    
    public static void print(int temp[]){
        for (int i=0;i

4.4 Java新特性对数组的支持

4.4.1 可变参数

  • 方法接收的参数不再是固定,可以随着需要来传递
  • 格式
返回值类型 方法名称(类型...参数名) {}
  • 向方法传递可变参数,其中参数是以数组形式保存下来的

示例:方法定义可变参数

public class TestDemo {
    public static void main(String[] args) {
        System.out.print("不传递参数:");
        fun();
        System.out.print("传递1个参数:");
        fun(1);
        System.out.print("传递5个参数:");
        fun(1,2,3,4,5);
    }

    public static void fun(int... args){
        for (int i=0;i

4.4.2 foreach输出

  • for循环的简洁用法
  • 格式
for(数据类型 变量名称 : 数组名称){
}

示例:

public class TestDemo {
    public static void main(String[] args) {
        System.out.print("不传递参数:");
        fun();
        System.out.print("传递1个参数:");
        fun(1);
        System.out.print("传递5个参数:");
        fun(1,2,3,4,5);
    }

    public static void fun(int... args){
        for(int x : args){
            System.out.print(x+"、");
        }
    }
}

运行结果和上面例子相同
  • foreach的主要作用是方面输出数组
    其他情况下,不建议使用foreach

你可能感兴趣的:(《Java开发实战经典》4 数组和方法)