一、昨日作业

1、设计一个方法,找出一个数组中最大的数字,连同所在的下标一起输出。

  1. public static void getMax(int[] array) {
  2. // 空数组判断
  3. if (array == null || array.length == 0) {
  4. System.out.println("空数组,没有元素,没有最大值");
  5. return;
  6. }
  7. // 1. 假设第0位的元素就是最大的
  8. int maxElement = array[0], maxIndex = 0;
  9. // 2. 从第1位元素开始遍历
  10. for (int i = 1; i < array.length; i++) {
  11. if (array[i] > maxElement) {
  12. // 记录新的最大值
  13. maxElement = array[i];
  14. // 记录新的最大值下标
  15. maxIndex = i;
  16. }
  17. }
  18. // 3. 输出结果
  19. System.out.println("数组中的最大值是: " + maxElement + ", 所在的下标是: " + maxIndex);
  20. }
  1. package com.qfedu.zuoye;
  2. /**
  3. * @Author laoyan
  4. * @Description TODO
  5. * @Date 2022/3/4 9:44
  6. * @Version 1.0
  7. */
  8. public class HomeWork01 {
  9. /**
  10. * 设计一个方法,找出一个整型数组中的第二大的值。
  11. * 1)不可以通过排序实现,不能修改数组中的数据顺序
  12. * 2)要考虑到最大的数字可能出现多次
  13. * @param args
  14. */
  15. public static void main(String[] args) {
  16. int[] arr = {10,38,9,12,12,36,38};
  17. if(arr.length>=2){
  18. int second = 0 ;
  19. int max = arr[0];
  20. // 为了 second不是最大的那一个
  21. for (int i = 0; i < arr.length; i++) {
  22. if(arr[i] != arr[0]){
  23. second = arr[i] > arr[0] ? arr[0] : arr[i];
  24. }
  25. }
  26. // 求出最大值
  27. for (int i = 0; i < arr.length; i++) {
  28. if(max <= arr[i]){
  29. max = arr[i];
  30. }
  31. }
  32. for (int i = 0; i < arr.length; i++) {
  33. if(arr[i] > second && arr[i] < max){
  34. second = arr[i];
  35. }
  36. }
  37. System.out.println("最大值是:"+max);
  38. System.out.println("第二大值是:"+second);
  39. }else{
  40. System.out.println("没有第二大值");
  41. }
  42. }
  43. }
  1. package com.qfedu.zuoye;
  2. /**
  3. * @Author laoyan
  4. * @Description TODO
  5. * @Date 2022/3/4 9:44
  6. * @Version 1.0
  7. */
  8. public class HomeWork02 {
  9. /**
  10. * 设计一个方法,找出一个整型数组中的第二大的值。
  11. * 1)不可以通过排序实现,不能修改数组中的数据顺序
  12. * 2)要考虑到最大的数字可能出现多次
  13. * @param args
  14. */
  15. public static void main(String[] args) {
  16. int[] arr = {38,38,9,12,12,36,38};
  17. int max = arr[0],min= arr[0];
  18. // 求出最大值
  19. for (int i = 0; i < arr.length; i++) {
  20. if(max <= arr[i]){
  21. max = arr[i];
  22. }
  23. if(min >= arr[i]){
  24. min = arr[i];
  25. }
  26. }
  27. int second = min;
  28. if(second < max){
  29. for (int i = 0; i < arr.length; i++) {
  30. if(max != arr[i] && second < arr[i]){
  31. second = arr[i];
  32. }
  33. }
  34. }
  35. System.out.println("最大值是:"+max);
  36. System.out.println("第二大值是:"+second);
  37. }
  38. }


2、设计一个方法,找出一个整型数组中的第二大的值。
1)不可以通过排序实现,不能修改数组中的数据顺序
2)要考虑到最大的数字可能出现多次

  1. public static int getSecondMax(int[] array) {
  2. // 特殊情况判断
  3. if (array == null || array.length == 0) {
  4. System.out.println("空数组");
  5. return -1;
  6. }
  7. if (array.length == 1) {
  8. System.out.println("只有一个元素,没有次大值");
  9. return -1;
  10. }
  11. // 声明两个变量,分别用来记录最大值和次大值
  12. int max = array[0], second = array[0];
  13. // 遍历数组中的每个元素
  14. for (int i : array) {
  15. if (i > max) {
  16. // 新的最大值出现了
  17. second = max;
  18. max = i;
  19. }
  20. else if (i > second && i < max) {
  21. // 新的次大值出现了
  22. second = i;
  23. }
  24. }
  25. return second;
  26. }


3、小明参加歌手比赛,评委组给出10个成绩,去掉一个最高分,去掉一个最低分,求平均分

  1. public static double getAverage(int[] scores) {
  2. // 1. 记录总成绩、最高成绩、最低成绩
  3. int sum = 0, max = scores[0], min = scores[0];
  4. // 2. 遍历所有成绩
  5. for (int score : scores) {
  6. // 计算总成绩
  7. sum += score;
  8. // 记录最高成绩
  9. if (score > max) {
  10. max = score;
  11. }
  12. // 记录最低成绩
  13. if (score < min) {
  14. min = score;
  15. }
  16. }
  17. // 3. 计算平均成绩
  18. return (sum - max - min) / (double)(scores.length / 2);
  19. }


4、已知方法 public static int[] combine(int[] arr1, int[] arr2) 的作用是,合并两个数组,
并对合并后的数组进行升序排序,返回这个数组。实现这个方法。

public static int[] combine(int[] arr1, int[] arr2) {
        // 1. 合并数组
        int[] combine = Arrays.copyOf(arr1, arr1.length + arr2.length);
        System.arraycopy(arr2, 0, combine, arr1.length, arr2.length);

        // 2. 排序
        Arrays.sort(combine);

        return combine;
    }
package com.qfedu.zuoye;

import java.util.Arrays;

/**
 * @Author laoyan
 * @Description TODO
 * @Date 2022/3/4 10:15
 * @Version 1.0
 */
public class HomeWork03 {
    /**
     * 已知方法 public static int[] combine(int[] arr1, int[] arr2) 的作用是,合并两个数组,
     * 并对合并后的数组进行升序排序,返回这个数组。实现这个方法。
     */
    public static int[] combine(int[] arr1, int[] arr2){
        int[] arr = new int[arr1.length + arr2.length];
        for (int i = 0; i < arr1.length; i++) {
            arr[i] = arr1[i];
        }
        for (int i = arr1.length; i < arr.length; i++) {
            arr[i] = arr2[i-arr1.length];
        }
        Arrays.sort(arr);
        return arr;

    }

    public static int[] combine2(int[] arr1, int[] arr2){
        int[] arr = Arrays.copyOf(arr1,arr1.length+arr2.length);

        for (int i = arr1.length; i < arr.length; i++) {
            arr[i] = arr2[i-arr1.length];
        }
        Arrays.sort(arr);
        return arr;

    }

    /**
     * System.arraycopy(original, 0, copy, 0,
     *                          Math.min(original.length, newLength));
     *
     */
    public static int[] combine3(int[] arr1, int[] arr2){
        int[] arr = Arrays.copyOf(arr1,arr1.length+arr2.length);
        System.arraycopy(arr2, 0, arr, arr1.length,arr2.length);

        Arrays.sort(arr);
        return arr;

    }

    public static void main(String[] args) {
       int[] arr = {1,3,6,8};
        int[] arr2 = {10,30,60,80};
        System.out.println(Arrays.toString(combine3(arr, arr2)));
    }
}


5、已知方法 public static int[] delete(int[] arr, int ele) 的作用是删除数组中第一次出现的ele元素,
并返回删除后的数组。实现这个方法。

public static int[] delete(int[] array, int element) {
        // 1. 计算下标
        int index = -1;
        for (int i = 0; i < array.length; i++) {
            if (array[i] == element) {
                index = i;
                break;
            }
        }

        // 2. 判断不存在
        if (index == -1) {
            return array;
        }

        // 3. 用后面的元素覆盖前面的
        System.arraycopy(array, index + 1, array, index, array.length - index - 1);
        return Arrays.copyOf(array, array.length - 1);
    }
package com.qfedu.zuoye;

import java.util.Arrays;

/**
 * @Author laoyan
 * @Description TODO
 * @Date 2022/3/4 10:27
 * @Version 1.0
 */
public class HomeWork04 {

    /*
       已知方法 public static int[] delete(int[] arr, int ele) 的作用是删除数组中第一次出现的ele元素,
        并返回删除后的数组。实现这个方法
        先找到要删除的元素在数组中的位置,然后声明一个新的数组,长度原来数组减一,循环老数组赋值给新数组,遇到要删除的元素,跳过
     */
    public static void main(String[] args) {
        int[] arr = {1,3,6,8};
        System.out.println(Arrays.toString(delete(arr, 10)));

    }
    public static int[] delete(int[] arr, int ele){
        int index = -1;
        int[] newArr = new int[arr.length - 1];
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == ele){
                index = i;
            }
        }
        if(index == -1){
            System.err.println("没有找到要删除的元素....");
            return arr;
        }else{
            int indexNew = 0;
            for (int i = 0; i < arr.length; i++) {
                if(arr[i] != arr[index]){
                    newArr[indexNew] = arr[i];
                    indexNew++;
                }
            }
        }
        return newArr;
    }
}

二、面向对象

1、概念
面向对象是一个抽象的概念,我们编程时尽可能的将代码中出现的对象都抽取出来,变成一个单独的类,这样的一种编程思想就是面向对象。
2、语法:

[访问权限修饰符] class 类名 {
    // 类体
    // 属性: 描述所有对象共有的特征。
    // 方法: 描述所有对象共有的行为。
}
package com.qfedu.day04_01;

/**
 * 
 *
 *   类: class 修饰的 就是类 需要跟上 {}
 *   一个.java 文件,可以有多个类,但是只能有一个public ,并且该类的类名一定要和文件名一致。
 *
 *   一个类中都有啥?  属性(全局变量)  方法(静态的,非静态的)   代码块(静态或非静态)
 *
 */
class Demo3 {
}
class Demo2 {
}
public class Demo {

    static {

    }
    int age; // 属性,全局变量
    public void show(){
        if(1> 2){
            System.out.println("");
        }
    }

}

3、类的实例化

package com.qfedu.day04_01;

/**
 * @Author laoyan
 * @Description TODO
 * @Date 2022/3/4 11:23
 * @Version 1.0
 */
public class Student {

    int age;  // 属性
    String name;

    public void playGame(){ // 方法 即 行为
        System.out.println("喜欢玩...I play you,you play me,相互play");
    }
    public void study(){
        System.out.println("学生都喜欢学大数据");
    }

}


package com.qfedu.day04_01;

/**
 * @Author laoyan
 * @Description TODO
 * @Date 2022/3/4 11:27
 * @Version 1.0
 *
 *    想要用一个类中的方法,如果不是静态的,必须先new才能调用,否则不行。
 *    调用静态方法不需要new.
 */
public class Demo02 {

    /*
         传递一个对象Student 打印信息
     */
    public static void showStu(Student stu){
        System.out.println(stu.age + "," +stu.name);
    }

    public static void main(String[] args) {
        Student student = new Student(); // student 就称之为Student类的一个对象
        Student student2 = new Student();
        student.age = 18;
        student.name="张三";
        student.playGame();
        student.study();

        Student stu3 = student ;

        showStu(student);
        showStu(new Student());// 匿名对象  没有名字的对象

    }
}

4、成员的分类

代码块,成员变量,方法 三种
每一种又根据静态非静态来划分。
静态的都是属于类的,不属于任何一个对象,调用时都是类名.   直接调用
非静态的都是属于某个对象的,必须先new 对象再调用。
静态代码块只在jvm加载类的时候调用一次
非静态代码块需要new 对象时调用,new 多少个对象就执行多少次。

一般工具类中的方法都是静态方法,方便调用。
package com.qfedu.day04_01;

/**
 * @Author laoyan
 * @Description TODO
 * @Date 2022/3/4 11:44
 * @Version 1.0
 */
public class StaticDemo {

    {
        System.out.println("我是非静态代码块");
    }

    static{
        System.out.println("我是静态代码块");
    }

    static int  num = 10;
    int num2= 8;
    public static void show(){
        System.out.println("我是静态方法");
    }
    public  void show2(){
        System.out.println("我是非静态方法");
    }

    public static void main(String[] args) {

        System.out.println(StaticDemo.num);
        StaticDemo.show();
        /**
         * 静态代码块在类被加载的那一刻就运行了,只运行一次。
         */

        /**
         * 只要是非静态的,就必须先有对象,再调用
         */
        StaticDemo staticDemo = new StaticDemo();
        System.out.println(staticDemo.num2);
        staticDemo.show2();
    }
}

5、this关键字
this的功能总结:

  • 1.用来区分成员变量和局部变量

    private String name ;
    
      public Dog(String name){
          this.name = name;
      }
    
  • 2.可以在构造方法内部调用其他重载的构造方法,提高代码的复用性,简化代码(具体实现见构造方法小节)

    public Dog(String name){
          this();
          this.name = name;
      }
      public Dog(){
          System.out.println("我就是构造方法");
      }
    

    6、构造方法

    什么是构造方法?   方法
    *       作用是构造, 构造类的实例化对象的。
    *       构造方法:
    *       1、没有返回值
    *       2、名字必须和类名一样。
    *       3、每一个类默认都有一个无参数的构造方法。
    *       4、如果你写了其他的有参数的构造方法,那么无参数的构造方法就消失了。
    

    ```java package com.qfedu.day04_01;

/**

  • @Author laoyan
  • @Description TODO
  • @Date 2022/3/4 14:46
  • @Version 1.0 *
  • 什么是构造方法? 方法
  • 作用是构造, 构造类的实例化对象的。
  • 构造方法:
  • 1、没有返回值
  • 2、名字必须和类名一样。
  • 3、每一个类默认都有一个无参数的构造方法。
  • 4、如果你写了其他的有参数的构造方法,那么无参数的构造方法就消失了。 */ public class Dog { private String name ;

    public Dog(String name){ this(); this.name = name; } public Dog(){ System.out.println(“我就是构造方法”); }

    public static void main(String[] args) { //Dog dog = new Dog(); Dog dog2 = new Dog(“旺财”); } }

7、类的封装性<br /> 属性都变私有,不让人随便访问,通过编写set/get 方法来访问,类的封装性<br />纯粹的这种类,我们称之为  实体类。
```java
Teacher teacher = new Teacher();
        teacher.setName("老闫");// 闫振伟
        System.out.println(teacher.getName());

8、静态方法在内存模型中的位置

//说明static
class  Student{
    int age;//非静态成员变量
    static  int height;//静态成员变量

    //静态方法
    public static void  jump(){
        System.out.println("jump");
    }
}
public class Demo2 {
    public static void main(String[] args) {
            Student s = new Student();
            s.age = 10;//引用调用非静态的成员变量
            //s.height = 23;//引用调用静态的成员变量

            //Student.age = 20;//类名不能调用非静态成员
            Student.height = 20;//类名只能直接调用静态成员
      Student.jump();//类名调用静态方法
    }
}
过程说明:
1.将Demo2.class对象加载进方法区
2.将静态方法-main()方法保存在静态方法区一份
3.将Student.class对象加载进方法区
4.将静态成员height,jump()保存在静态方法区一份,同时height初始化成0
5.main()方法入栈
6.执行main()中的代码,创建局部变量s
7.在栈中创建Student对象,给非静态成员变量age初始化成0,并将地址返回,保存在引用s中
8.给age赋值成10
9.给height赋值成20
10.jump()方法入栈

9、课堂训练

package com.qfedu.day04_01;

/**
 * @Author laoyan
 * @Description TODO
 * @Date 2022/3/4 15:44
 * @Version 1.0
 *
 * 已知一个书签(BookMark)具有属性:页码和备注
 *  此类的用处巨大:  其实就是一个  口袋
 *
 *     public  void  show(BookMark bm){
 *
 *     }
 *
 *     public void  show(String node,int page){
 *
 *     }
 */
public class BookMark{

    private int page;
    private String note;

    public BookMark() {
    }

    public BookMark(int page, String note) {
        this.page = page;
        this.note = note;
    }

    @Override
    public String toString() {
        return "BookMark{" +
                "page=" + page +
                ", note='" + note + '\'' +
                '}';
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }
}
package com.qfedu.day04_01;

/**
 * @Author laoyan
 * @Description TODO
 * @Date 2022/3/4 15:51
 * @Version 1.0
 */
public class TestBookMark {
    public static void main(String[] args) {
        BookMark[] marks = new BookMark[5];
        marks[0] = new BookMark(10,"西游记");
        marks[1] = new BookMark(17,"水浒传");
        marks[2] = new BookMark(24,"红楼梦");
        marks[3] = new BookMark(60,"遥远的救世主");
        marks[4] = new BookMark(89,"狼图腾");
        //在一个数组中,存储了5个书签(BookMark,直接使用上一题的类即可)。输出所有的页码范围在 [20, 50] 范围内的书签
        for (BookMark bm:marks) {
            if(bm.getPage() >=20 && bm.getPage() <=50){
                System.out.println(bm); // 打印一个对象其实调用的是该对象的toString 方法。
            }
        }
    }
}

10、Debug 模式调试代码
image.png
使用Debug运行程序,需要在有疑问的地方打断点。
image.png
image.png
image.png 从不是断点的代码页面返回到断点的页面。
image.png 一步步运行,碰到是一个整的方法,不会进入到方法内部,直接运行完。
image.png 一步步运行,进入到你编写的方法内部查看里面的运行步骤。
image.png 可以直接进入源码的方法中查看运行情况。
image.png 从别的方法中出来,每次只能出一层。
image.png 将光标回退到 该方法被调用的地方。
image.png

image.png 重新运行debug模式
image.png 从一个断点直接运行到另一个断点处
image.png 结束程序,不调试了
image.png 展示所有的断点
image.png 取消项目中所有的断点,断点变灰色了,再次点击,所有断点又恢复了。