day07_面向对象01

day07复习

1. 数组整体的概述

1. (了解)数组的理解:多个相同数据类型的变量按照一定顺序组织起来的集合
2. (重点)一维数组的使用
	① 数组的声明与初始化
	② 数组元素的调用
	③ 数组的长度
	④ 数组的遍历
	⑤ 数组元素默认初始化值
	⑥ 数组的内存解析
3. (重点)二维数组的使用
	① 数组的声明与初始化
	② 数组元素的调用
	③ 数组的长度
	④ 数组的遍历
	⑤ 数组元素默认初始化值
	⑥ 数组的内存解析
4. (重点)数组中常见算法的使用
5. (熟悉)Arrays工具类的使用
6. (熟悉)数组中的常见异常
	> ArrayIndexOutOfBoundsException
	> NullPointerException

2. 数组中常见算法的使用

2.1 数组的定义及元素的赋值

  • 练习
package com.atguigu.exer;

/**
 * 使用二维数组打印一个 10 行杨辉三角。
 *
 * 【提示】
 *  1. 第一行有 1 个元素, 第 n 行有 n 个元素
 *  2. 每一行的第一个元素和最后一个元素都是 1
 *  3. 从第三行开始, 对于非第一个元素和最后一个元素的元素。即:
 *   yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
 *
 *
 *   说明:笔试中数组是作为算法考察的一大门类(另一大门类就是考察String);
 *        数组中的考察,其中一部分是创建特殊要求的数组。比如:杨辉三角,回形数等。
 *
 *   拓展1:
 *   创建一个长度为6的int型数组,要求数组元素的值都在1-30之间,且是随机赋值。
 *   同时,要求元素的值各不相同。
 *   拓展2:
 *   回形数
 *
 * @author shkstart
 * @create 9:21
 */
public class YangHuiAngleTest {
    public static void main(String[] args) {
        //1. 创建一个二维数组
        int[][] yangHui = new int[10][];

        //2. 通过循环的方式,创建内层的数组
        for(int i = 0;i < yangHui.length;i++){
            yangHui[i] = new int[i + 1];
            //3. 给数组元素赋值
            //3.1 给每行的首末元素赋值为1
            yangHui[i][0] = yangHui[i][i] = 1;
            //3.2 给每行的非首末元素赋值:yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
            //if(i > 1){
                for(int j = 1;j < yangHui[i].length - 1;j++){
                    yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j];
                }
            //}
        }

        //4. 二维数组的遍历
        for(int i = 0;i < yangHui.length;i++){
            for(int j = 0;j < yangHui[i].length;j++){
                System.out.print(yangHui[i][j] + "\t");
            }
            System.out.println();
        }
    }
}

  • 练习:创建一个长度为6的int型数组,要求数组元素的值都在1-30之间,且是随机赋值。同时,要求元素的值各不相同。
  • 回形数
从键盘输入一个整数(1~20) 
则以该数字为矩阵的大小,把1,2,3…n*n 的数字按照顺时针螺旋的形式填入其中。例如: 输入数字2,则程序输出: 1 2 4 3 
输入数字3,则程序输出: 1 2 3 8 9 4 7 6 5 
输入数字4, 则程序输出: 
1   2   3   4 
12  13  14  5 
11  16  15  6 
10   9  8   7

2.2 数值类型数组中特殊值的计算

package com.atguigu.java;

/**
 * 数组的常见算法一:求数值型数组中元素的最大值、最小值、平均数、总和等
 *
 * @author shkstart
 * @create 9:48
 */
public class ArrayTest {
    public static void main(String[] args) {

        int[] arr = new int[]{3,42,2,53,65,24,65,87,-95,-84,0,45};

        //获取最大值
        int max = arr[0];
        for(int i = 1;i < arr.length;i++){
            if(max < arr[i]){
                max = arr[i];
            }
        }
        System.out.println("最大值为:" + max);

        //获取最小值
        int min = arr[0];
        for(int i = 1;i < arr.length;i++){
            if(min > arr[i]){
                min = arr[i];
            }
        }
        System.out.println("最小值为:" + min);

        //获取总和
        int sum = 0;
        for(int i = 0;i <arr.length;i++){
            sum += arr[i];
        }
        System.out.println("总和为:" + sum);

        //求平均数
        double avg = (double)sum / arr.length;
        System.out.println("平均数为:" + avg);
    }

}

2.3 数组的反转、复制、遍历、查找等

package com.atguigu.java;

/**
 * 数组的常见算法二:复制、反转、查找、遍历
 * @author shkstart
 * @create 10:21
 */
public class ArrayTest1 {

    public static void main(String[] args) {
        int[] arr = new int[]{3,42,2,53,65,24,65,87,-95,-84,0,45};

        //复制
        int[] arrCopy = new int[arr.length];
        for (int i = 0; i < arrCopy.length; i++) {
            arrCopy[i] = arr[i];
        }


        //遍历
        for (int i = 0; i < arr.length; i++) {
            if(i == 0){
                System.out.print("{");
            }else if(i == arr.length - 1){
                System.out.print(arr[i] + "}");
                break;
            }
            System.out.print(arr[i] +",");
        }

        //反转方式一:
//        for(int i = 0,j = arr.length - 1; i < j ;i++,j--){
//            int temp = arr[i];
//            arr[i] = arr[j];
//            arr[j] = temp;
//        }

        //反转方式二:
        for(int i = 0;i < arr.length / 2;i++){
            int temp = arr[i];
            arr[i] = arr[arr.length - 1 - i];
            arr[arr.length - 1 - i] = temp;
        }

        System.out.println();
        //遍历arr1
        for (int i = 0; i < arr.length; i++) {
            if(i == 0){
                System.out.print("{");
            }else if(i == arr.length - 1){
                System.out.print(arr[i] + "}");
                break;
            }
            System.out.print(arr[i] +",");
        }

        //查找(或搜索):如果查找到了,打印其在数组中的索引;如果没找到,打印没有找到的提示
        //线性查找
        int target = 244;
        boolean isFlag = true;
        for(int i = 0;i < arr.length;i++){
            if(target == arr[i]){
                System.out.println("查找到了" + target +"元素,索引位置为:" + i);
                isFlag = false;
                break;
            }
        }

        if(isFlag){
            System.out.println("不好意思,没找到");
        }

        //二分法查找:了解
        //二分法查找:要求此数组必须是有序的。
        int[] arr3 = new int[]{-99,-54,-2,0,2,33,43,256,999};
        boolean isFlag1 = true;
        int number = 256;
        number = 25;
        int head = 0;//首索引位置
        int end = arr3.length - 1;//尾索引位置
        while(head <= end){
            int middle = (head + end) / 2;
            if(arr3[middle] == number){
                System.out.println("找到指定的元素,索引为:" + middle);
                isFlag1 = false;
                break;
            }else if(arr3[middle] > number){
                end = middle - 1;
            }else{//arr3[middle] < number
                head = middle + 1;
            }
        }

        if(isFlag1){
            System.out.println("未找打指定的元素");
        }

    }
}

  • 练习
使用简单数组
 * (1)创建一个名为ArrayTest的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
 * (2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
 * (3)显示array1的内容。
 * (4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。
 * 打印出array1。   array2 = array1;
public class ArrayTest {
    public static void main(String[] args) {
        int[] array1,array2;

        array1 = new int[]{2,3,5,7,11,13,17,19};

        //遍历array1
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }

        //赋值array2变量等于array1
        array2 = array1;

        //修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)
        for(int i = 0;i < array2.length;i++){
            if(i % 2 == 0){
                array2[i] = i;
            }
        }
        System.out.println("**************");
        //遍历array1
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }
    }
}


对应的内存结构:
在这里插入图片描述

  • 拓展
 * 思考:array1和array2是什么关系? 两个数组变量指向了堆空间中同一个数组结构
 *
 * 拓展:修改题目,实现array2对array1数组的复制
public class ArrayTest1 {
    public static void main(String[] args) {
        int[] array1,array2;

        array1 = new int[]{2,3,5,7,11,13,17,19};

        //遍历array1
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }

        //实现array2数组对array1数组的复制
        array2 = new int[array1.length];
        for(int i = 0;i < array2.length;i++){
            array2[i] = array1[i];
        }

        //修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)
        for(int i = 0;i < array2.length;i++){
            if(i % 2 == 0){
                array2[i] = i;
            }
        }
        System.out.println("**************");
        //遍历array1
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }
    }
}

对应的内存结构:
在这里插入图片描述

2.4 数组的排序

衡量排序算法的优劣:
1.时间复杂度:分析关键字的比较次数和记录的移动次数
2.空间复杂度:分析排序算法中需要多少辅助内存
3.稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的。

排序算法分类:内部排序和外部排序。
内部排序:整个排序过程不需要借助于外部存储器(如磁盘等),所有排序操作都在内存中完成。
外部排序:参与排序的数据非常多,数据量非常大,计算机无法把整个排序过程放在内存中完成,必须借助于外部存储器(如磁盘)。外部排序最常见的是多路归并排序。可以认为外部排序是由多次内部排序组成。

  • 十大经典的排序算法
    在这里插入图片描述
最好能手写实现的排序方式:冒泡排序、快速排序
能说清楚排序实现原理的:堆排序、归并排序
  • 冒泡排序的实现
package com.atguigu.java;

/**
 * 冒泡排序的实现
 *
 * @author shkstart
 * @create 11:18
 */
public class BubbleSortTest {
    public static void main(String[] args) {

        int[] arr = new int[]{3, 42, 2, 53, 65, 24, 65, 87, -95, -84, 0, 45};
        //排序前的遍历
        for (int i = 0; i < arr.length; i++) {
            if (i == 0) {
                System.out.print("{");
            } else if (i == arr.length - 1) {
                System.out.print(arr[i] + "}");
                break;
            }
            System.out.print(arr[i] + ",");
        }

        //排序操作:冒泡排序
        for(int i = 0;i < arr.length - 1;i++){
            for(int j = 0;j < arr.length -1 - i;j++){
                if(arr[j] > arr[j + 1]){
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }


        System.out.println();
        //排序后的遍历
        for (int i = 0; i < arr.length; i++) {
            if (i == 0) {
                System.out.print("{");
            } else if (i == arr.length - 1) {
                System.out.print(arr[i] + "}");
                break;
            }
            System.out.print(arr[i] + ",");
        }

    }
}

  • 快速排序的实现原理:

    • 第一轮
      在这里插入图片描述

    • 后续n轮:在这里插入图片描述

  • 各种排序算法的时间复杂度、空间复杂度、稳定性的情况
    在这里插入图片描述

2.5 其他的算法

[32,34,-36,76,3,-67,-78,9,3,-79,3,-5,9]

3. Arrays工具类的使用

package com.atguigu.java1;

import java.util.Arrays;

/**
 *
 * 测试Arrays的使用
 *
 * Arrays:操作数组的工具类,在java.util包下提供
 *
 * @author shkstart
 * @create 11:40
 */
public class ArraysTest {
    public static void main(String[] args) {
        //1. boolean equals(int[] a,int[] b)
        int[] arr1 = new int[]{1,2,3,4,5};
        int[] arr2 = new int[]{1,2,4,3,5};
        System.out.println(Arrays.equals(arr1, arr2));

        //2. String toString(int[] a)
        System.out.println(arr1);//[I@1540e19d

        System.out.println(Arrays.toString(arr1));

        //3. void fill(int[] a,int val)
        Arrays.fill(arr1,10);
        System.out.println(Arrays.toString(arr1));

        //4. void sort(int[] a)
        int[] arr3 = new int[]{3, 42, 2, 53, 65, 24, 65, 87, -95, -84, 0, 45};
        Arrays.sort(arr3);
        System.out.println(Arrays.toString(arr3));

        //5. int binarySearch(int[] a,int key)
        System.out.println(Arrays.binarySearch(arr3, 53));

    }
}

4. 常见异常

  • ArrayIndexOutOfBoundsException
		//1. 数据角标越界的异常:ArrayIndexOutOfBoundsException
        //角标的合法范围为:[0,数组长度-1]
        int[] arr = new int[10];
//        System.out.println(arr[10]);
        //System.out.println(arr[-1]);
  • NullPointerException
		//2. 空指针异常:NullPointerException
        //情况1:
        int[] arr1 = new int[10];
        arr1 =  null;
        //System.out.println(arr1[0]);

        //情况2:
        int[][] arr2 = new int[10][];
        //System.out.println(arr2[0][0]);

        //情况3:后面面向对象内容中最常见的情况
        String[] arr3 = new String[]{"AA","BB"};
        arr3 = new String[4];
        System.out.println(arr3[0].toString());

5. 面向对象的理解

  • 学习面向对象的三条主线
 * 面向对象部分内容学习的三条主线:
 * 1. 类及类的成员:属性、方法、构造器(或构造方法);代码块、内部类
 * 2. 面向对象的三大特征:封装性、继承性、多态性、(抽象性)
 * 3. 其它关键字的使用:this\super\static\final\package\import\abstract\interface...
  • 面向对象 vs 面向过程
* 面向过程,强调的是功能行为,以函数为最小单位,考虑怎么做。
 * 面向对象,将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
 *
 *
 * 举例:把大象装进冰箱。
 *
 * 面向过程:
 * 1. 把冰箱门打开
 * 2. 拿起大象,放进冰箱
 * 3. 把冰箱门关住
 *
 * 面向对象:
 *
 *  冰箱{
 *      开开(){
 *
 *      }
 *      合上(){
 *
 *      }
 *  }
 *
 * 大象{
 *      进入(冰箱){
 *
 *      }
 *
 * }
 *
 * 人{
 *     打开(冰箱){
 *         冰箱.开开();
 *     }
 *     拿起(大象){
 *         大象.进入(冰箱);
 *     }
 *     关闭(冰箱){
 *         冰箱.合上();
 *     }
 * }

6. 类与对象

在这里插入图片描述

 * 类是对一类事物的描述,是抽象的、概念上的定义
 * 对象是实际存在的该类事物的每个个体,因而也称为实例(instance)

7. 类的内部设计

/**
 * 设计类,其实就是设计类的内部结构。
 *
 * 1. 名词解释:
 *  属性 = 成员变量 = field = 域、字段
 *
 *  方法 = 成员方法 = method = 函数(function)
 *
 *  对象 = 实例
 *
 *  创建对象 = 类的实例化
 */
  • 代码演示
class Person{ //类:人
    //设计类,就是设计类的内部成员
    //首当其中,就是设计类的属性、方法
    //成员一:属性
    String name;
    int age;

    //成员二:方法
    public void eat(){
        System.out.println("人吃饭");
    }
    public void sleep(){
        System.out.println("人睡觉");
    }

    public void think(){
        System.out.println("人思考");
    }
}

使用上述设计的类:

public class PersonTest {  //测试类

    public static void main(String[] args) { //程序的入口
        //创建Person类的对象
        //数据类型 变量名 = 变量值
        int num = 10;

        int[] arr = new int[10];
        Scanner scann = new Scanner(System.in);

        Person per = new Person();//创建了Person类的对象

        //通过对象调用属性:“对象.属性”
        //per.name = "江学振";
        System.out.println(per.name);

        per.age = 23;
        System.out.println(per.age);

        //通过对象调用方法:“对象.方法()”
        per.eat();
        per.sleep();
        per.think();

        Person per1 = new Person();
        per.age = 30;
        System.out.println(per1.age);//30

        Person per2 = per;//per 和 per2指向了堆空间中的同一个对象实体
        per2.age = 40;
        System.out.println(per2.age);//40
        System.out.println(per.age);//40
    }

}
  • 总结(很重要)
如何由类创建对象以及实现功能的调用?
 *  第1步:创建类,并设计类的内部成员。(属性、方法)
 *  第2步:创建类的对象 (或类的实例化)
 *  第3步:通过“对象.属性” 或 “对象.方法()” 的方式,完成功能的实现
  • 内存解析
    在这里插入图片描述

在这里插入图片描述

 * 总结:对象的内存解析
 *   1. 对象名的变量保存在栈空间中
 *       对象实体保存在堆空间中,对象的属性也保存在堆空间中。
 *   2. 如果创建类的多个对象,则每个对象拥有一套类的属性。如果修改其中一个对象的属性a的值,不会影响
 *     其它对象的属性a的值。

8. 类的成员变量

  • 代码演示
class Phone{
    //属性:成员变量
    String phoneName;
    double price;

    //方法
    public void call(){
        int hour = 1; //局部变量
        System.out.println("手机打了" + hour + "小时的电话");
    }
    public void sendMessage(String message){ //message:局部变量
        System.out.println("发送短信:" + message);
    }
    public void playGame(String game){//game:局部变量
        System.out.println("玩游戏:" + game);
    }
}

//测试类
public class PhoneTest {
    public static void main(String[] args) {
        Phone p1 = new Phone();
        System.out.println(p1.phoneName);
        System.out.println(p1.price);

        p1.sendMessage("有内鬼,终止交易");
    }
}
总结:
 * 1. 复习:变量的分类: ① 按照数据类型: 基本数据类型  vs 引用数据类型
 *                    ② 按照在类中声明的位置: 成员变量  vs 局部变量
 *
 * 2. 对比成员变量  vs 局部变量
 *     相同点:都是变量,定义的格式相同的。
             都有作用域,在其声明的作用域内是有效的。
 *     不同点:
 *          ① 类中声明的位置不同
 *              成员变量:直接声明在类中
 *              局部变量:方法内部、方法的形参、构造器内部、构造器形参、代码块内部等
 *          ② 在内存中分配的位置不同
 *              成员变量:分配在堆空间中
 *              局部变量:分配在栈空间中
 *          ③ 成员变量声明以后,可以有默认赋值。
 *                  整型:0
 *                  浮点型:0.0
 *                  字符型:0 或 \u0000
 *                  boolean型:false
 *                  引用类型:null
 *
 *            而局部变量在调用前,必须显式赋值,因为没有默认赋值。
 *          ④ 成员变量可以在声明前,添加权限修饰符。
 *            而局部变量不能使用权限修饰符进行修饰。
 *            (此时的权限修饰符有:public \ private \ protected \缺省)
 *
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值