Java核心基础之方法和数组

Java核心基础之方法和数组

Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机, Java 仍是企业和开发人员的首选开发平台。
  

课程内容的介绍

1. 方法
2. 数组
  

一、方法

1. Eclipse导入项目
实现准备了一个小游戏的案例,导入 Eclipse 中运行,导入的方式 File -- Import。

代码被复制到了工作空间:

导入工作空间中文乱码了,我们可以修改下当前项目的编码方式。

   
2.方法概念的引入
2.1 方法和没有使用方法的对比
没有使用方法的情况
package com.bobo.funcation;

public class FunDemo01 {
    /**
    * 为什么要使用方法
    * @param args
    */
    public static void main(String[] args) {
        // 在控制台输出 1 到 100的偶数
        for (int i = 1 ; i <= 100 ; i++) {
            if(i % 2 == 0){
                System.out.println(i);
            }
        }
        // 在控制台输出300 到500的偶数
        for (int i = 300 ; i <= 500 ; i++) {
            if(i % 2 == 0){
                System.out.println(i);
            }
        }
        // 在控制台输出200 到1000的偶数
        for (int i = 200 ; i <= 1000 ; i++) {
            if(i % 2 == 0){
                System.out.println(i);
            }
        }
    }
}
  
使用方法的情况
package com.bobo.funcation;

public class FunDemo02 {
    /**
    * 为什么要使用方法
    * @param args
    */
    public static void main(String[] args) {
        // 在控制台输出 1 到 100的偶数
        printEven(1, 100);
        // 在控制台输出300 到500的偶数
        printEven(300, 500);
        // 在控制台输出200 到1000的偶数
        printEven(200, 1000);
    }
    /**
    * 我们定义的第一个方法
    * 作用:输入 x 到 y之间的所有的偶数
    * @param x
    * @param y
    */
    public static void printEven(int x,int y){
        for (int i = x ; i <= y ; i++) {
            if(i % 2 == 0){
                System.out.println( i);
            }
        }
    }
}
   
2.2 方法的概念
一段用来完成特定功能的代码片段。
/**
* 我们定义的第一个方法
* 作用:输入 x 到 y之间的所有的偶数
* @param x
* @param y
*/
public static void printEven(int x,int y){
    for (int i = x ; i <= y ; i++) {
        if(i % 2 == 0){
            System.out.println( i);
        }
    }
}
   
2.3 为什么使用方法
1. 程序中多次使用到的功能。
2. 便于程序的阅读。
3. 提供程序的重用性。
在其他语言中,方法又称为 函数
  

3.方法的定义
3.1 方法的语法规则
访问修饰符 返回值类型 方法名称(参数类型 参数1 , 参数类型 参数2 ...){
    方法体;
    return 返回值;
}
访问修饰符 : 暂时使用 public static . 后面我们会在面向对象的课程中详细介绍这部分的内容。
返回值类型 : 该方法的返回结果的数据类型,可以是八大基本数据类型也可以是引用类型 [ 后面介绍 ]。
方法名称 : 自定义的,符合 标识符 的命名规则即可,见名知意。
参数 :表明该方法要完成特定功能所需要的支持。
  
实际参数【实参】:水果榨汁机案例中,具体放进榨汁机中的水果,比如 苹果,西瓜等。
方法调用时的参数,也就是实际参与运算的参数。

  
形式参数【形参】:水果榨汁机案例中,这个机器在设计的时候定义的外部要给与的类型方法定义时的参数,用于接收实际的参数。

    
参数类型:参数的数据类型,可以是八大基本数据类型和引用类型。
参数名:就是变量名,满足标识符的命名规则几个。
方法体 :就是完成特定功能的代码,具体根据需求来确定。
返回值 :方法特定功能的结果,通过过 return 返回给调用者的,哪里调用的就返回到哪里去。
   
3.2 方法的具体实现
3.2.1 方法写在哪?
// 位置 5
public class FunDemo03 {
    // 位置 1
    public static void main(String[] args) {
        // 位置 2
    }
    // 位置 3
}
// 位置 4
  
1. 首先方法和方法是平级的关系, main 方法也是一个方法,所以方法是不能写在 main 方法中的。
2. 方法只能定义在类以内。不能单独的写到类以外。
3. 一个类中可以包含任意个方法,没有先后顺序。
   
3.2.2 课堂案例
1. 求两个数之和
/**
* 求两个数之和
* @param x
* @param y
* @return
*/
public static int add(int x,int y){
    int sum = x + y; // 方法体
    return sum;
}
   
2. 键盘录入年份判断是否是闰年
package com.bobo.funcation;

import java.util.Scanner;

public class FunDemo05 {
    /**
    * 键盘录入年份判断是否是闰年
    * 1.把方法的基本结构定义出来
    * 2.根据得到的年份实现闰年判断的逻辑
    * @param args
    */
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("请输入一个年份:");
        int year = in.nextInt();
        boolean flag = isLeapYear(year);
        if(flag){
            System.out.println(year + "是闰年");
        }else{
            System.out.println(year + "不是闰年");
        }
    }
    /**
    * 判断 year 是否是闰年
    * 闰年的规则:
    * 1.year能被4整除同时year不能被100整除
    * 2.或者year能被400整除
    * @param year
    * @return
    */
    public static boolean isLeapYear(int year){
        if((year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0){
            // 表示满足闰年的条件
            return true;
        }
        return false;
    }
}
   
3. 键盘录入数据,返回两个数中较大的值
package com.bobo.funcation;

import java.util.Scanner;

public class FunDemo06 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("请输入两个要比较的整数:");
        int x = in.nextInt();
        System.out.println("再输入一个:");
        int y = in.nextInt();
        int max = max(x, y);
        System.out.println(x + " 和 " + y +"中值大的是:"+ max);
    }
    // 键盘录入数据,返回两个数中较大的值
    public static int max(int i , int j){
        /*if(i >= j){
            return i;
        }
        return j;*/
        return i >= j ? i : j;
    }
}
   
4. 输出 1 100 之间的所有的素数
package com.bobo.funcation;

public class FunDemo07 {
    public static void main(String[] args) {
        for(int i = 2; i < 100; i ++){
            // 调用方法判断是否是素数
            if(isPrimeNumber(i)){
                System.out.println(i);
            }
        }
    }
    /**
    * 输出1到1000之间的所有的素数
    * 比1大的整数中,除了1和它本身以外,不再有别的因数,这种整数叫做 质数或者素数
    * i = 7 7%2 7%3 7%4 7%5 7%6
    * i=23 23%2 23%3 .... 23%22
    * @param num
    * @return
    */
    public static boolean isPrimeNumber(int num){
        boolean isPrime = true; // 默认是素数
        // 让 num 对 2到num-1 取余,如果结果都不为0说明是素数否则不是
        for(int j = 2 ; j <= num/2 ; j++){
            if(num % j == 0){
                // 说明不是素数
                isPrime = false;
                break;
            }
        }
        return isPrime;
    }
}
   
输出的结果:
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
   
3.3 方法的调用
方法在定义完成之后,如果没有被调用是永远不会执行的! main 方法之所以不会被调用,是因为main方法是由 Java 虚拟机调用的, main 方法是程序的唯一入口。
   
方法的调用三要素:
1. 需要什么类型的参数就传什么类型的参数。
2. 返回什么类型的值就拿什么类型的变量来接收。
3. 实参的数目、数据类型、和次序必须和调用方法声明的形参列表匹配。
   
方法的调用的三种方式
1. 输出调用:输出调用适用于直接显示结果。
2. 赋值调用:适用于有返回结果的,并且返回值可以后续继续使用。
3. 直接调用:适用于没有返回值,只需要执行方法即可。
   
方法如果没有返回结果,可以省略掉 return 关键字;
public static void show(){
    System.out.println("HelloWorld");
    return ;
}
   
4.方法的重载
在一个类中可以定义有相同名称,但参数列表不同的多个方法,调用的时候回根据不同的参数列表类选择对应的方法。
参数列表不同:参数的个数,顺序,类型不同。
重载的特点:
1. 发生在同一个类中。
2. 方法名称相同。
3. 参数列表不同 ( 类型、个数、顺序 )。
4. 和返回类型没有关系。
相关面试题:介绍下 Java 中的重写和重载的区别?
  
5.递归
5.1 什么是递归
方法中调用本地方法,自己调用自己
   
5.2 递归的注意事项
1. 递归一定要有出口,否则很容易出现死递归,走不出来,类似死循环。
2. 递归的次数太多,容易出现内存溢出的情况。
3. 构造方法不能递归【后面的内容】。

   
5.3 递归的案例
5.3.1 n的阶乘计算
package com.bobo.funcation;

public class FunDemo11 {
    /**
    * 求n的阶乘 5 ! 5*4*3*2*1
    * @param args
    */
    public static void main(String[] args) {
        //System.out.println(getFactorial(10));
        System.out.println(getFactorialRecursion(10));
    }
    /**
    * 通过递归的方式来实现N的阶乘计算
    * 分析 递归的出口
    * 5!=5*4!=5*4*3!
    * @param num
    * @return
    */
    public static int getFactorialRecursion(int num){
        if(num < 0){
            return 0;
        }
        // 先确定递归的出口
        if( num == 0 || num == 1){
            return 1;
        }else{
            return num * getFactorialRecursion(num-1);
        }
    }
    /**
    * 普通的获取num的阶乘
    * @param num
    * @return
    */
    public static int getFactorial(int num){
        if(num <=0 ){
            return 0;
        }
        int factorial = 1;
        for( int i = 1 ; i <= num;i++){
            factorial *= i;
        }
        return factorial;
    }
}

  
5.3.2 斐波拉契数列
斐波拉契数列,又称黄金分割数列,因数据集列昂多 . 斐波拉契以兔子繁殖为例而引入,又称为 " 兔子数列"
1 1 2 3 5 8 13 21 34 ......
计算第 N 个位的值是多少。
package com.bobo.funcation;

public class FunDemo12 {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(getFibonacci(9));
    }
    /**
    * 获取斐波拉契数列
    * @return
    */
    public static int getFibonacci(int n){
        // 定位到 出口
        if(n == 1 || n == 2){
            return 1;
        }
        return getFibonacci(n-1) + getFibonacci(n-2);
    }
}
   
实现过程分解:

   

二、数组

1.为什么要使用数组
byte short int long
double float
boolean
char
String
问题: Java 考试结束后,需要统计全班学员的平均分 (30 个人 )
解决方案:定义 30 个变量,然后相加求和,并计算平均分。
更好的解决方案:数组 数据容器。
    
2.内存分配
2.1 硬盘
持久化我们的数据。
2.2 内存
运行时存储,在软件 ( 程序 ) 运行的时候开辟空间,软件运行结束后,内存中的数据就会消失。
Java 程序运行的时候,系统分配的 内存, Java 程序是怎么利用的?
FunDemo01.java 这个 Java 文件肯定是存储在硬盘上的。但是当我们通过 javac FunDemo01.java -->FunDemo01.class -->
java FunDemo01 执行 这个过程中内存是怎么分配的 ?
   
2.3 Java程序的内存分区
内存划分的结构图

   
局部变量:方法体内定义的变量 或者 方法定义时声明的变量【形参】
public class ArrayDemo01 {
    // 定义一个全局变量
    int sum = 30;
    public static void main(String[] args) {
        // 定义一个局部变量
        int i = 10;
    }
}
   
2.4 Java虚拟机栈的特点
1. 先进后出 (Firt in last out FILO), 类似于子弹夹。
2. 栈区中的数据仅在作用域内有效,使用完毕之后立马自动释放。
3. 栈内的变量没有默认值,如果没有给出默认值就直接报错。
   
2.5 堆区的特点
1. 堆区中的每个变量都有默认值
byte short int long 默认的都是 0
float double 默认的 0.0
char 默认的是 '\u0000' 就是一个空字符
boolean 默认值 false
引用类型 默认值是 null
2. 凡是 new 出来的东西都在堆区 开辟空间,堆区开辟的空间都会有地址值。
3. 在堆区中的对象,一旦使用完毕之后,不会立刻消失,会等待垃圾回收期空闲的时候自动回收。
   
3.数组的初始化
3.1 数组的语法格式
数据类型[] 数组名 = new 数据类型[数组的长度];
数据类型 数组名[] = new 数据类型[数组的长度];
public static void main(String[] args) {
    // 定义一个数组
    int[] array1 = new int[5];
    int array2[] = new int[10];
}
   
数组其实也一个变量,存储相同类型的一组数据。
作用:告诉计算机数据类型是什么。
   
特点:
1. 数据类型相同。
2. 数组名实际上就是一个变量,既然是变量,那就必须先赋值在使用。
3. 数组的每一个元素既可以是基本数据类型,也可以是引用数据类型。
   
A " 张三 " ," 李四 " ,“ 王五
B 9 , 99, "c", 12
C 98.1 ,33.3 ,45
  
3.2 数组的内存分配
上面的数组的语法格式其实有两步组成。
1. 数组的声明
int[] array1;
    
声明的变量会在内存中划分一块合适的空间,栈区。

  
2. 数组的赋值
arra1 = new int[5];
   
将内存划分出来的一串连续的内存空间的地址赋值给了变量。

   
3.3 数组的赋值
在前面介绍的 arra1 = new int[5]; 数组中的每个元素会根据数组的类型赋予默认值,那么我们可以通过数组的下标来获取数组中的各个位置上的元素,在Java 中数组的下标是从 0 开始的 , 最大的下标length- 1。
如果我们从数组中获取元素的下表超过的数组的长度会出错,下表越界。
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
   
下标不能是负数。
java.lang.ArrayIndexOutOfBoundsException: -1
  
我想要修改数组中对应位置中的元素。
public static void main(String[] args) {
    int i = 10;
    // 定义一个数组
    int[] array1 = new int[3];
    array1[0] = 5;
    array1[1] = 6;
    array1[2] = 7;
    System.out.println(array1[0]);
    System.out.println(array1[1]);
    System.out.println(array1[2]);
}
   
简化的初始化方式。
在初始化的时候就为每个元素赋值,不需要指明长度。
public static void main(String[] args) {
    //int[] a1 = new int[7];
    // 声明变量后直接将一个数组赋值给了这个变量
    int a1[] = {1,2,3,4,5,6,7,8,9};
    System.out.println(a1[0]);
    System.out.println(a1[3]);
    System.out.println(a1[4]);
    System.out.println(a1[5]);
    System.out.println(a1[6]);
}
   
注意事项:
1. 标识符:数组的名称,用于区分不同的数组。
2. 数组元素:向数组中存放的数据。
3. 元素下标,从 0 开始,数据中的每个元素都可以通过下标来访问。
4. 元素类型:数组元素的数据类型。
   
4. 数组的遍历
前面我们是通过下标一个个从数组中取出元素的,这种在数组中元素比较多的情况下,会比较麻烦这时我们可以考虑使用前面介绍的循环来实现。
public static void main(String[] args) {
    //int[] a1 = new int[]{1,2,3,4,5,6,7,8,9};
    int a1[] = {1,2,3,4,5,6,7,8,9};
    // 通过遍历的形式获取数组中的每个元素
    System.out.println(a1[0]);
    System.out.println(a1[1]);
    System.out.println(a1[2]);
    System.out.println(a1[3]);
    System.out.println(a1[4]);
    System.out.println(a1[5]);
    System.out.println(a1[6]);
    System.out.println(a1[7]);
    System.out.println(a1[8]);
    for(int i = 0 ; i < a1.length ; i ++){
        System.out.println(a1[i]);
    }
}
    
案例:将数组转换为如下格式的字符串。
[33,55,77,999]
/**
* 将数组转换为如下格式的字符串
* [33,55,77,999]
* 解决的思路:
* 1.声明一个字符串 String arrayStrinig = "[";
* 2.变量获取数组中的每个元素 拼接在 arrayString中
* 3.在循环结束后 将 "]" 拼接到arrayString的结尾
* @param a
* @return
*/
public static String arrayToString(int[] a){
    String arrayString = "[";
    for(int i = 0 ; i < a.length; i ++){
        if(i == a.length-1){
            // 获取数组中的最后一个元素
            arrayString += a[i];
        }else{
            arrayString += a[i]+",";
        }
    }
    arrayString += "]";
    return arrayString;
}
   
5. 课堂案例
5.1 计算5个学员的平均分
public class ArrayDemo05 {
    /**
    * 计算5个学员的平均分
    *
    * @param args
    */
    public static void main(String[] args) {
        double[] score = {67,89,87,68,54};
        // 记录学员总分
        double sum = 0;
        for(int i = 0 ; i < score.length; i ++){
            sum += score[i];
        }
        System.out.println("5个学员的平均分是:" + sum/5);
    }
}
    
5.2 有一个数列: 8,4,1,0,25,199,33
A 循环输出数列值
B 求数列中所有数值的和
C 求出最大值
D 将数组倒置并输出
E 数组查找 猜数字游戏:从键盘中任意输入一个数字判断是否在数列中
F 数组排序
package com.bobo.array;

import java.util.Scanner;

public class ArrayDemo06 {
    /**
    * 5.2 有一个数列: 8,4,1,0,25,199,33
    • A 循环输出数列值
    • B 求数列中所有数值的和
    • C 求出最大值
    • D 将数组倒置并输出
    • E 数组查找 猜数字游戏:从键盘中任意输入一个数字判断是否在数列中
    • F 数组排序
    * @param args
    */
    public static void main(String[] args) {
        int[] a = { 8,4,1,0,25,199,33};
        printArray(a);
        System.out.println("数列中所有值的和:" + getSum(a));
        System.out.println("数列中的最大值是:" + getMax(a));
        // 将数组倒置
        reverseArray2(a);
        printArray(a);
        Scanner input = new Scanner(System.in);
        System.out.println("请输入一个数字:");
        int num = input.nextInt();
        System.out.println(num + "是否在数列中:" + isContainsNumInArray(a, num));
    }
    /**
    * 循环输出数列值
    * @param a
    */
    public static void printArray(int[] a){
        for(int i = 0 ; i< a.length ; i++){
            System.out.println(a[i]);
        }
    }
    /**
    * 求数列中所有数值的和
    * @param a
    * @return
    */
    public static int getSum(int[] a){
        int sum = 0 ;
        for(int i = 0 ; i < a.length ;i ++){
            sum += a[i];
        }
        return sum;
    }
    /**
    * 求出最大值
    * 8,4,1,0,25,199,33
    * @param a
    */
    public static int getMax(int[] a){
        int max = 0 ;
        for(int i = 0 ; i < a.length ; i ++){
            if(max < a[i]){
                max = a[i];
            }
        }
        return max;
    }
    /**
    * 将数组倒置并输出
    * 8,4,1,0,25,199,33
    * 33 199 25 0 1 4 8
    *
    */
    public static int[] reverseArray1(int[] a){
        int[] b = new int[a.length];
        for(int i = a.length-1 ,j=0; i >= 0; i--,j++){
            b[j] = a[i];
        }
        return b;
    }
    /**
    * 将数组倒置并输出
    * 8,4,1,0,25,199,33
    * 33 199 25 0 1 4 8
    * 第一个数和最后一个数交换位置
    * a[0] 和 a[a.length-1 -0]
    * int temp = 0;
    * temp = a[0]
    * a[0] = a[a.length-1 -0]
    * a[a.length-1 -0]=temp
    *
    * 第二个和倒数第二个交换位置
    * a[1] 和 a[a.length-1 -1]
    *
    * 假设 a.length = 7 3次 a.length/2
    * 假设 a.length = 6 3次
    * 假设 a.length = 5 2次
    * 4 2次
    * 3 1次
    * 2 1次
    * 1 0次
    */
    public static void reverseArray2(int[] a){
        for(int i=0 ; i < a.length/2 ;i++){
            int temp = 0 ;
            temp = a[i];
            a[i] = a[a.length-1-i];
            a[a.length-1-i] = temp;
        }
    }
    /**
    * 数组查找 猜数字游戏:从键盘中任意输入一个数字判断是否在数列中
    * @param a
    * @return
    */
    public static boolean isContainsNumInArray(int[] a,int num){
        for(int i = 0 ; i < a.length ; i ++){
            if(num == a[i]){
                return true;
            }
        }
        return false;
    }
}
   
排序下个内容单独介绍
  

6.排序
将一个无序的数组转换为一个有序的数组。
    
6.1 冒泡排序
冒泡排序:从第一个数据开始,一次比较相邻元素的大小。如果前者大于后者,则进行交换操作。把大的元素往后交换。通过多轮迭代,直到没有交换操作为止。冒泡排序就像是在一个水池中处理数据一样,每次会把最大的那个数据传递到最后。
package com.bobo.array;

import java.util.Arrays;

public class ArrayDemo08 {
    /**
    * 冒泡排序
    * 1 4 3 5 2
    * 1 3 4 2 5
    * @param args
    */
    public static void main(String[] args) {
        int[] a = {1,4,3,5,2};
        System.out.println("排序前:" );
        System.out.println(Arrays.toString(a));
        // 第一趟排序
        /*for (int i = 0 ; i < a.length-1-0 ; i++) {
            if(a[i] > a[i+1]){
                int temp = 0 ;
                temp = a[i];
                a[i] = a[i+1];
                a[i+1] = temp;
            }
        }
        System.out.println("第一趟排序后:");
        System.out.println(Arrays.toString(a));
        // 最后一位数值肯定是最大的
        // 第二趟排序
        for (int i = 0 ; i < a.length-1-1 ; i++) {
            if(a[i] > a[i+1]){
                int temp = 0 ;
                temp = a[i];
                a[i] = a[i+1];
                a[i+1] = temp;
            }
        }
        System.out.println("第二趟排序后:");
        System.out.println(Arrays.toString(a));
        // 第三趟排序
        for (int i = 0 ; i < a.length-1-2 ; i++) {
            if(a[i] > a[i+1]){
                int temp = 0 ;
                temp = a[i];
                a[i] = a[i+1];
                a[i+1] = temp;
            }
        }
        System.out.println("第三趟排序后:");
        System.out.println(Arrays.toString(a));
        // 第四趟排序
        for (int i = 0 ; i < a.length-1-3 ; i++) {
            if(a[i] > a[i+1]){
                int temp = 0 ;
                temp = a[i];
                a[i] = a[i+1];
                a[i+1] = temp;
            }
        }
        System.out.println("第四趟排序后:");
        System.out.println(Arrays.toString(a));*/
        /*for(int i = 0 ; i < a.length-1; i ++){
            for(int j = 0 ; j < a.length-1 - i; j ++ ){
                if(a[j] > a[j+1]){
                    int temp = 0 ;
                    temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                }
            }
        }*/
        bubbleSort(a);
        System.out.println("冒泡排序后:");
        System.out.println(Arrays.toString(a));
    }
    public static void bubbleSort(int[] a){
        for(int i = 0 ; i < a.length-1; i ++){
            for(int j = 0 ; j < a.length-1 - i; j ++ ){
                if(a[j] > a[j+1]){
                    int temp = 0 ;
                    temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                }
            }
        }
    }
}

   
6.2 选择排序
选择排序的规则:从最左侧开始,依次和后面的每个元素进行比较,小了向前移动,每趟结束后,最小的元素会出现在最前面。
package com.bobo.array;

import java.util.Arrays;

public class ArrayDemo09 {
    /**
    * 选择排序
    * @param args
    */
    public static void main(String[] args) {
        int[] a = {1,4,3,5,2};
        System.out.println("排序前:" );
        System.out.println(Arrays.toString(a));

        /*// 第一趟
        int i = 0 ;
        for(int j = 1 ; j < a.length; j ++){
            if(a[j] < a[i]){
                int temp = 0 ;
                temp = a[j];
                a[j] = a[i];
                a[i]=temp;
            }
        }
        System.out.println("第一趟排序:");
        System.out.println(Arrays.toString(a));

        // 第2趟
        i = 1 ;
        for(int j = 2 ; j < a.length; j ++){
            if(a[j] < a[i]){
                int temp = 0 ;
                temp = a[j];
                a[j] = a[i];
                a[i]=temp;
            }
        }
        System.out.println("第2趟排序:");
        System.out.println(Arrays.toString(a));

        // 第3趟
        i = 2 ;
        for(int j = 3 ; j < a.length; j ++){
            if(a[j] < a[i]){
                int temp = 0 ;
                temp = a[j];
                a[j] = a[i];
                a[i]=temp;
            }
        }
        System.out.println("第3趟排序:");
        System.out.println(Arrays.toString(a));

        // 第4趟
        i = 3 ;
        for(int j = 4 ; j < a.length; j ++){
            if(a[j] < a[i]){
                int temp = 0 ;
                temp = a[j];
                a[j] = a[i];
                a[i]=temp;
            }
        }
        System.out.println("第4趟排序:");
        System.out.println(Arrays.toString(a));*/
        /*for(int i = 0 ; i < a.length -1 ; i++){
            for(int j = i+1 ; j < a.length; j ++){
                if(a[j] < a[i]){
                    int temp = 0 ;
                    temp = a[j];
                    a[j] = a[i];
                    a[i]=temp;
                }
            }
        }*/
        selectSort(a);
        System.out.println("选择排序:");
        System.out.println(Arrays.toString(a));
    }
    public static void selectSort(int[] a){
        for(int i = 0 ; i < a.length -1 ; i++){
            for(int j = i+1 ; j < a.length; j ++){
                if(a[j] < a[i]){
                    int temp = 0 ;
                    temp = a[j];
                    a[j] = a[i];
                    a[i]=temp;
                }
            }
        }
    }
}
   
6.3 排序效率的测评
选择排序和冒泡排序哪个效率高?我们通过测试数据来看看。
package com.bobo.array;

import java.util.Arrays;

public class ArrayDemo01 {
    /**
    * 测试选择排序和冒泡排序效率的
    * 对同一个数组分别通过冒泡和选择对数组进行排序
    * 用时最短的表示效率高
    * System.currentTimeMillis()
    * 返回从1970年1月1日0时0分0秒 距今已经过去了多少毫秒
    * @param args
    */
    public static void main(String[] args) {
        //System.out.println(System.currentTimeMillis());
        //1606024168239 1606024180015 1606024186015
        //System.out.println(System.currentTimeMillis()/1000/60/60/24/365);
        double[] d = new double[100000];
        for(int i = 0 ; i < d.length ;i ++){
            d[i] = Math.random();
        }
        // 记录开始的时间
        long start = System.currentTimeMillis();
        // 冒泡排序
        //bubbleSort(d);
        // 选择排序
        //selectSort(d);
        // 快速排序
        Arrays.sort(d);
        long end = System.currentTimeMillis();
        System.out.println(end-start);
    }
    /**
    * 冒泡排序
    * @param a
    */
    public static void bubbleSort(double[] a){
        for(int i = 0 ; i < a.length-1; i ++){
            for(int j = 0 ; j < a.length-1 - i; j ++ ){
                if(a[j] < a[j+1]){
                    double temp = 0 ;
                    temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                }
            }
        }
    }
    /**
    * 选择排序
    * @param a
    */
    public static void selectSort(double[] a){
        for(int i = 0 ; i < a.length -1 ; i++){
            for(int j = i+1 ; j < a.length; j ++){
                if(a[j] < a[i]){
                    double temp = 0 ;
                    temp = a[j];
                    a[j] = a[i];
                    a[i]=temp;
                }
            }
        }
    }
}
  
7.查找
想要从数组中快速找到我们需要的元素,如果我要查找某个位置上的元素,那么我可以通过下标快速的找到,但是如果我们不知道数组中有哪些元素,而我们又需要找这个元素,那么此时我们应该怎么办呢?
  
7.1 顺序查找
从数据的第一个元素开始变量,找了就结束遍历,否则直到遍历完成。
package com.bobo.array;

public class ArrayDemo02 {
    public static void main(String[] args) {
        int[] d = {1,2,3,4,5,6,7,8,9,10};
        System.out.println(basicSelect(d, 11));
    }
    public static boolean basicSelect(int[] a,int num){
        for(int i = 0 ; i < a.length ; i ++){
            if(a[i] == num){
                return true;
            }
        }
        return false;
    }
}
    
7.2 折半查找(二分查找)
前提条件:只能够针对排好序的数据进行查找。
查找思路:每次都实现查找数据的中间元素,将需要找的数据和中间那个元素进行比较,这样查找可以减少至少一半的效率。

    
8.增强版for循环
增强版 for 循环也称为 foreach 循环。相对于之前的普通 for 循环要简洁一些。
语法格式:
for(元素类型 元素变量 : 遍历对象 ){
    // 循环体 使用元素变量
}
package com.bobo.array;

public class ArrayDemo04 {
    /**
    * for(元素类型 元素变量 : 遍历对象 ){
        // 循环体 使用元素变量
    }
    * @param args
    */
    public static void main(String[] args) {
        int[] a = {11,22,33,44,55,66};
        for(int i : a){
            System.out.println(i);
        }
        for(int i = 0 ; i < a.length ; i ++){
            System.out.println(a[i]);
        }
    }
}
    
foreach 循环和 for 循环对比:
1. foreach 循环更适合遍历数据。
2. foreach 循环没有下标,普通 for 循环适合做添加,删除操作。
3. 本质上面 foreach 循环就是普通 for 循环。

   
9. 可变的参数列表
可变参数列表的语法规则
参数类型 ... 变量名称
package com.bobo.array;

public class ArrayDemo05 {
    /**
    * 方法的形参中出现了 类型相同,个数不同的情况,这时我们可以使用 可变参数列表来实现
    * @param args
    */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(add(1,2));
        System.out.println(add(1,2,3));
        System.out.println(add(1,2,3,4));
        add();
    }
    /* public static int add(int a,int b){
        return a + b ;
    }
    public static int add(int a,int b,int c){
        return a + b + c;
    }*/
    public static int add(int ... a){
        System.out.println(a);
        int sum = 0 ;
        for(int i : a){
            sum += i;
        }
        return sum;
    }
}
    
可变参数的特点:
1. ... 的位置 放在参数类型和变量名之间即可。
2. 可变参数列表必须出现在参数列表的最后面,而且一个方法的形参中最多只能有一个可变参数列表。
3. 可变参数列表本质上就是数组,既然是数组那么就可以按照数组的思路来处理。
  
10. Arrays工具
Java 中提供了一个针对于数组操作的工具类, Arrays。
package com.bobo.array;

import java.util.Arrays;

public class ArrayDemo06 {
    /**
    * Arrays工具类介绍
    *
    * @param args
    */
    public static void main(String[] args) {
        int[] a = {11,7,22,33,99,225,44,66,55,66,87,7};
        int[] b = {11,7,22,33,99,225,44,66,55,66,87,7};
        // 将数组转换为一个字符串
        System.out.println(Arrays.toString(a));
        // 排序
        // Arrays.sort(a);
        // 指定某个范围内的数据排序
        //Arrays.sort(a, 3, 8);
        System.out.println(Arrays.toString(a));
        // 二分查找
        int index = Arrays.binarySearch(a, 661);
        System.out.println(index);
        // 判断两个数组是否相等
        System.out.println(Arrays.equals(a, b));
        // 给数组中的元素填充内容
        // Arrays.fill(a, 1);
        // 局部填充
        Arrays.fill(a, 2, 5, 1);
        System.out.println(Arrays.toString(a));
        // 复制数组
        int[] c = Arrays.copyOf(a, a.length-2);
        System.out.println(Arrays.toString(c));
        // 指定范围复制
        int d[] = Arrays.copyOfRange(a, 3, 7);
        System.out.println(Arrays.toString(d));
    }
}
   
统计三个班上每个学员的成绩,计算班级的平均分和总分。
A 67 78 88 90 78
B 99 90 87
C 56 99
    
11. 二维数组
11.1 语法格式介绍
概念:本质上就是一个存放了一维数据的数组。
语法规则:
//格式1:
数据类型[][] 变量名 = new 数据类型[m][n];
//m:表示一个二维数组中有m个一维数组
//n:每个一维数组中有n个元素

//格式2:
数据类型 变量名[][] = new 数据类型[m][n];
//格式3
数据类型[] 变量名[] = new 数据类型[m][n];
m必不可少,n可写可不写
 
/**
* 二维数组
* @param args
*/
public static void main(String[] args) {
    int[] a = new int[4];
    int[][] arr = new int[3][2];
    int arr1[][] = new int[3][2];
    int[] arr2[] = new int[3][2];
}
   
注意: Java 中并没有真正意义上的二维数组,本质上就是一个存放了一维数组的数组。
数组中的每个元素还是一个数组,那么二维数组中每一个元素的值应该是地址值。
   

11.2 二维数组的内存图
n 初始指定的情况下:
package com.bobo.array;

public class ArrayDemo07 {
    /**
    * 二维数组
    * @param args
    */
    public static void main(String[] args) {
        /*int[][] arr = new int[3][2];
        int arr1[][] = new int[3][2];
        int[] arr2[] = new int[3][2];
        int[][] arr3 = new int[3][];*/
        int arr[][] = new int[3][2];
        System.out.println(arr);
        System.out.println(arr[0]); //[I@15db9742
        System.out.println(arr[1]); //[I@6d06d69c
        System.out.println(arr[2]); //[I@7852e922
        //System.out.println(arr[3]); // 数组 越界
        System.out.println(arr[0][0]); // 0
        System.out.println(arr[0][1]); // 0
        System.out.println(arr[1][0]); // 0
        //System.out.println(arr[0][2]);// 数组 越界
        arr[0][0] = 100;
        arr[0][1] = 200;
        arr[1][0] = 300;
        System.out.println(arr[0][0]); // 100
        System.out.println(arr[0][1]); // 200
        System.out.println(arr[1][0]); // 300
    }
}

n 初始不指定的情况下:
package com.bobo.array;

public class ArrayDemo08 {
    public static void main(String[] args) {
        int[][] arr = new int[3][];
        System.out.println(arr);
        System.out.println(arr[0]); //null
        System.out.println(arr[1]); //null
        System.out.println(arr[2]); //null
        // System.out.println(arr[0][0]);
        arr[0] = new int[3];
        arr[1] = new int[2];
        arr[2] = new int[1];
        System.out.println(arr[0][0]); // 0
        System.out.println(arr[0][1]); // 0
        System.out.println(arr[1][0]); // 0
        //System.out.println(arr[1][2]);// 数组 越界
        arr[0][0] = 100;
        arr[0][1] = 200;
        arr[1][0] = 300;
        //arr[2][2] = 400;
        System.out.println(arr[0][0]); // 100
        System.out.println(arr[0][1]); // 200
        System.out.println(arr[1][0]); // 300
    }
}

   
11.3 二维数组的静态初始化
// 一维数组中的静态初始化
int arr[] = new int[]{1,2,3,4,5,6};
int arr[] = {1,2,3,4,5,6};
int[][] arr = new int[][]{{},{},{}};
int[][] arr = {{},{},{}};
public static void main(String[] args) {
    int[][] arr = new int[][]{{11,22,33},{44,55},{66,77,88,99}};
    int[][] arr1 = {{11,22,33},{44,55},{66,77,88,99}};
}
      
针对二维数组的遍历
package com.bobo.array;

import java.util.Arrays;

public class ArrayDemo09 {
    public static void main(String[] args) {
        int[][] arr = new int[][]{{11,22,33},{44,55},{66,77,88,99}};
        int[][] arr1 = {{11,22,33},{44,55},{66,77,88,99}};
        int a0[] = arr[0];
        System.out.println(Arrays.toString(a0));
        int a1[] = arr[1];
        System.out.println(Arrays.toString(a1));
        int a2[] = arr[2];
        System.out.println(Arrays.toString(a2));
        System.out.println("----------");
        arrayPrintToString(arr);
    }
    public static void arrayPrintToString(int[] ... arr){
        for(int i = 0 ; i < arr.length ; i++){
            //System.out.println(Arrays.toString(arr[i]));
            // arr[i] 又是一个新的一维数组 那么我就可以按照一维数组的处理方式来处理了
            for(int j = 0 ; j < arr[i].length; j++){
                System.out.print(arr[i][j] + "\t");
            }
            System.out.println();
        }
    }
}
   
foreach 循环效果
package com.bobo.array;

import java.util.Arrays;

public class ArrayDemo09 {
    public static void main(String[] args) {
        int[][] arr = new int[][]{{11,22,33},{44,55},{66,77,88,99}};
        int[][] arr1 = {{11,22,33},{44,55},{66,77,88,99}};
        int a0[] = arr[0];
        System.out.println(Arrays.toString(a0));
        int a1[] = arr[1];
        System.out.println(Arrays.toString(a1));
        int a2[] = arr[2];
        System.out.println(Arrays.toString(a2));
        System.out.println("----------");
        arrayPrintToString(arr);
    }
    public static void arrayPrintToString(int[] ... arr){
        /*for(int i = 0 ; i < arr.length ; i++){
            //System.out.println(Arrays.toString(arr[i]));
            // arr[i] 又是一个新的一维数组 那么我就可以按照一维数组的处理方式来处理了
            for(int j = 0 ; j < arr[i].length; j++){
                System.out.print(arr[i][j] + "\t");
            }
            System.out.println();
        }*/
        for(int[] x : arr){
            for(int y : x){
                System.out.print(y + "\t");
            }
            System.out.println();
        }
    }
}
     
二维数组遍历的规律:
1. 外层循环控制一维数组的个数。
2. 内存循环控制每一个一维数组的元素个数。        
      
11.4 课堂案例
1. 统计三个班级中的学员的成绩的平均分
package com.bobo.array;

public class ArrayDemo10 {
    /**
    * 1.统计三个班级中的学员的成绩的平均分
    * @param args
    */
    public static void main(String[] args) {
        int score[][] = {{78,87,90,93,78},{67,76,84},{45,80}};
        // 总分
        int sum = 0 ;
        int num = 0; // 记录总的学员数量
        for(int[] ss:score){
            for(int s:ss){
                sum+=s;
                num++;
            }
        }
        System.out.println("统计获取总的平均分:"+sum/num);
    }
}
    
2. 键盘输入一个值,打印对应的杨辉三角图案
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
    
规则:
1. n 行有 n 列,类似于九九乘法表。
2. 每一行的第一列和最后一列的值为 1。
3. 从第三行开始,除了第一列和最后一列,每个元素的值等于上一行的前一列加上上一行的本列的值之和。
package com.bobo.array;

import java.util.Scanner;

public class ArrayDemo11 {
    /**
    * 规则:
    1. n行有n列,类似于九九乘法表
    2. 每一行的第一列和最后一列的值为1
    3. 从第三行开始,除了第一列和最后一列,
    每个元素的值等于上一行的前一列加上上一行的本列的值之和
    * @param args
    */
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("请输入杨辉三角的行数:");
        int n = in.nextInt();
        // 创建二维数组
        int[][] arr = new int[n][n];
        // 给二维数组赋值
        // a.给每一行的第一列和最后一列的值为1
        for(int i = 0 ; i < arr.length; i ++){
            // 没循环一次取出一行
            arr[i][0] = 1;
            arr[i][i] = 1;
        }
        // b.从第三行开始,除了第一列和最后一列,
        // 每个元素的值等于上一行的前一列加上上一行的本列的值之和
        for(int i = 2 ; i < arr.length ; i ++){
            for(int j = 1 ; j < arr.length-1 ; j++){
                arr[i][j] = arr[i-1][j-1] + arr[i-1][j];
            }
        }
        printArray(arr);
    }
    public static void printArray(int[][] arrays){
        /*for(int[] array : arrays){
            for(int a:array){
                System.out.print(a + "\t");
            }
            System.out.println();
        }*/
        for(int i = 0 ; i < arrays.length ; i ++){
            for(int j = 0 ; j <= i ; j++){
                System.out.print(arrays[i][j] + "\t");
            }
            System.out.println();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

方寸之间不太闲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值