Java程序设计

主讲教师: 郑如滨 副教授 / 集美大学

教学进度:
  • 预报名
  • 进行中
  • 已结束

学时安排:56学时

学分:3.5分

主要讲解Java程序设计。课程不仅包含讲授理论的视频,还包含在线编程练习。从理论与实践两个方面带领学生进入Java面向对象编程世界。课程每章均设有章节测验,并提供完整课件的下载,方便自学。课程中的丰富资源可为教师开展SPOC教学提供有力支撑。本课程制作精良、内容丰富,为福建省精品线上一流课程。
  • 10917966

    累计页面浏览量

  • 19800

    累计选课人数

  • 23634

    累计互动次数

2024-06-25 10:01 郑如滨 集美大学 在Java程序设计课程中提问:

思考(可选):ArrayList源代码分析

尝试阅读ArrayList内部的源代码,回答: 1.ArrayList内部使用什么来存储元素?尝试截图。 2.为什么可以用这种类型的数组来存储任何对象? 3.既然可以使用这种通用类型的数组存放任何元素,为什么还需要泛型技术?

  • 2025-01-15 18:54 朱勋飞

    尝试阅读ArrayList内部的源代码,回答:

    1.ArrayList内部使用什么来存储元素?尝试截图。

    2.为什么可以用这种类型的数组来存储任何对象?

    3.既然可以使用这种通用类型的数组存放任何元素,为什么还需要泛型技术?
  • 查看全部(150条)

2024-06-25 10:00 郑如滨 集美大学 在Java程序设计课程中提问:

练一练:HashSet

新建HashSet对象,往里面依次加入加入”abc”,”zbc”,”acb”。然后使用foreach打印出里面的元素。 1.贴出你的代码。 2.观察输出结果。输出元素的顺序与放入元素的顺序一致吗?尝试分析原因。 3.尝试使用迭代器遍历输出HashSet,贴出你的代码。

  • 2025-01-15 18:54 朱勋飞

    1.下面是创建HashSet对象,并依次加入元素"abc"、“zbc”、“acb”,然后使用foreach打印出里面元素的代码:
    import java.util.HashSet;

    public class HashSetExample {
    public static void main(String[] args) {
    // 创建HashSet对象
    HashSet<String> hashSet = new HashSet<>();

    // 往HashSet中添加元素
    hashSet.add("abc");
    hashSet.add("zbc");
    hashSet.add("acb");

    // 使用foreach打印出HashSet中的元素
    System.out.println("使用foreach打印HashSet中的元素:");
    for (String element : hashSet) {
    System.out.println(element);
    }
    }
    }
    2.观察输出结果,你会发现输出元素的顺序与放入元素的顺序不一定一致。这是因为HashSet是基于HashMap实现的,它不保证元素的顺序。HashSet存储元素时,会使用元素的hashCode值来确定元素的存储位置,因此元素可能会按照hashCode值的顺序被存储。由于"abc"、"zbc"和"acb"的hashCode值不同,它们在HashSet中的顺序可能与添加顺序不同。
    3.代码如下:
    import java.util.HashSet;
    import java.util.Iterator;

    public class Main {
    public static void main(String[] args) {
    // 创建HashSet对象
    HashSet<String> hashSet = new HashSet<>();

    // 往HashSet中添加元素
    hashSet.add("abc");
    hashSet.add("zbc");
    hashSet.add("acb");

    // 使用迭代器打印出HashSet中的元素
    System.out.println("使用迭代器打印HashSet中的元素:");
    Iterator<String> it = hashSet.iterator();
    while (it.hasNext())
    {
    String str= it.next();
    System.out.println(str);
    }
    }
    }
  • 查看全部(136条)

2024-06-25 10:00 郑如滨 集美大学 在Java程序设计课程中提问:

思考:ArrayList与LinkedList的区别

1. 如果想要像访问数组那样访问集合,适合使用什么接口及实现类? 2. 尝试阅读ArrayList与LinkedList代码,其内部分别使用什么方式来存储加到里面的元素?他们的get方法实现一样吗? 3. ArrayList与LinkedList共同之处有哪些?有何不同之处? 4.

  • 2025-01-15 18:54 朱勋飞

    1. 代码中 ArrayAlg 的静态嵌套类 Pair 的作用是用于存储和返回数组中的最小值和最大值两个值,将它们作为一个整体进行传递和处理。
    2. 将其定义为静态嵌套类的好处有:

    - 静态嵌套类不依赖于外部类的实例,可以直接通过外部类名访问,如 ArrayAlg.Pair ,使代码更加清晰简洁。
    - 静态嵌套类可以访问外部类的静态成员,在这个例子中,如果需要访问外部类的静态方法或变量会很方便。
    - 增强了代码的封装性,将 Pair 类与外部类 ArrayAlg 的逻辑紧密结合,同时又不会对外部类的实例造成影响。
    3. 如果将 public static class Pair 改成 public class Pair ,需要将 Pair 类从 ArrayAlg 类中提取出来作为一个独立的类。然后在 ArrayAlg 类的 minmax 方法中返回的类型需要改为新的独立的 Pair 类的类型。并且在 StaticInnerClassTest 类中,需要引入新的 Pair 类。
  • 查看全部(123条)

2024-06-25 09:30 郑如滨 集美大学 在Java程序设计课程中提问:

思考(可选):Cloneable接口

1.对String[] arr = {"a","b","cdef"}调用clone()方法能否实现arr数组的深拷贝?为什么? 2.尝试使用代码进行验证

  • 2025-01-15 18:54 朱勋飞

    在Java中,对`String[] arr = {"a", "b", "cdef"}`调用`clone()`方法可以实现数组的**浅拷贝**,而不是深拷贝

    ### 浅拷贝 vs 深拷贝

    - **浅拷贝(Shallow Copy)**:
    - 创建一个新的数组对象,但数组中的元素仍然是原数组元素的引用(对于对象类型)或值(对于基本数据类型)。
    - 对于`String`数组,由于`String`是不可变的(immutable),浅拷贝通常是可以接受的,因为修改字符串不会影响原数组。

    - **深拷贝(Deep Copy)**:
    - 创建一个新的数组对象,并且递归地复制数组中的所有元素及其包含的对象。
    - 对于包含可变对象的数组,深拷贝是必要的,以确保原数组和拷贝数组完全独立。

    ### 具体分析

    对于`String[] arr = {"a", "b", "cdef"}`:

    ```java
    String[] arr = {"a", "b", "cdef"};
    String[] clonedArr = arr.clone();
    ```

    - `arr.clone()`会创建一个新的`String`数组`clonedArr`,其长度与`arr`相同。
    - `clonedArr`中的每个元素都是`arr`中对应元素的副本。由于`String`是不可变的,这意味着即使你修改了`clonedArr`中的某个字符串(例如通过重新赋值),也不会影响`arr`中的相应元素。

    ### 示例代码

    ```java
    public class CloneExample {
    public static void main(String[] args) {
    String[] arr = {"a", "b", "cdef"};
    String[] clonedArr = arr.clone();

    // 修改clonedArr中的一个元素
    clonedArr[2] = "xyz";

    // 打印原数组和克隆数组
    System.out.println("Original array: " + Arrays.toString(arr));
    System.out.println("Cloned array: " + Arrays.toString(clonedArr));
    }
    }
    ```

    ### 输出

    ```
    Original array: [a, b, cdef]
    Cloned array: [a, b, xyz]
    ```

    从输出可以看出,修改`clonedArr`中的元素并没有影响`arr`,这验证了对于`String`数组,浅拷贝是有效的。

    ### 总结

    - 对于`String[]`数组,调用`clone()`方法可以实现数组的浅拷贝,由于`String`的不可变性,这种拷贝在大多数情况下是可以接受的。
    - 如果数组中包含可变对象,或者你需要完全独立的副本,那么需要实现深拷贝。

    ### 深拷贝示例(包含可变对象)

    如果数组中包含可变对象,例如`StringBuilder`,则需要手动实现深拷贝:

    ```java
    public class DeepCopyExample {
    public static void main(String[] args) {
    StringBuilder[] arr = {new StringBuilder("a"), new StringBuilder("b"), new StringBuilder("cdef")};
    StringBuilder[] deepCopiedArr = new StringBuilder[arr.length];

    for (int i = 0; i < arr.length; i++) {
    deepCopiedArr[i] = new StringBuilder(arr[i]);
    }

    // 修改deepCopiedArr中的一个元素
    deepCopiedArr[2].append("xyz");

    // 打印原数组和深拷贝数组
    System.out.println("Original array: " + Arrays.toString(arr));
    System.out.println("Deep copied array: " + Arrays.toString(deepCopiedArr));
    }
    }
    ```

    ### 输出

    ```
    Original array: [a, b, cdef]
    Deep copied array: [a, b, cdefxyz]
    ```

    从输出可以看出,修改`deepCopiedArr`中的元素并没有影响`arr`,这验证了深拷贝的有效性。
  • 查看全部(115条)

2024-06-24 23:21 郑如滨 集美大学 在Java程序设计课程中提问:

练一练:在Eclipse中查看String等常用类的代码

1.在Eclipse中关联jdk源代码。并截图。 参考资料:http://www.kafan.cn/edu/55668554.html 2.查看Math类的源代码,截图Math.PI与Math.E的值。并回答: 2.1 Math属于什么包? 2.2 PI与E为什么要声明为static fina

  • 2025-01-15 18:53 朱勋飞

    查看 Math 类的源代码:
    1、Math 属于 java.lang 包。
    2、PI 与 E 声明为 static final 的原因是,它们是常量,不会改变的数值。static 表示它们属于类,而不是对象的实例;final 表示它们的值在初始化后不能被改变。
    3、不能使用 new 创建一个 Math 对象,因为 Math 是一个工具类(utility class),它不包含构造方法,所有方法都是 static 的,设计上就是用来直接通过类名调用的。

    String 类的内部使用字符数组(char 数组)存储字符串。在Java 8及以后的版本中,为了提高性能和内存使用效率,String 类的实现可能会使用一种优化的存储方式,称为String Interning,但这并不改变基本的存储结构。

    Random 类属于 java.util 包,而 Arrays 类也属于 java.util 包。这两个类都提供了一组静态方法,用于操作数组或生成随机数
  • 查看全部(122条)

2024-06-24 23:20 郑如滨 集美大学 在Java程序设计课程中提问:

思考:什么时候使用static?

1. 定义类的时候,什么样的方法和属性应该声明为static,什么样的方法和属性不声明为static? 2. Person类的name、age、getAge等是否应该声明为static? 3. 为什么String的valueOf方法声明为static,而substring方法不声明为static

  • 2025-01-15 18:53 朱勋飞

    1. 在静态方法`show()`中,`System.out.println(id);`不会出错,因为`id`是一个静态成员变量,可以在静态方法中直接访问。而`System.out.println(radius);`会出错,因为`radius`是一个实例变量,无法在静态方法中直接访问。

    出错原因是实例变量`radius`是与特定对象关联的,而静态方法是与类关联的。在静态方法中无法使用`this`关键字引用当前对象,因为静态方法不依赖于任何特定的实例。只有在实例方法中才可以使用`this`关键字引用当前对象。

    2. 静态方法内部不能使用`this`关键字是因为静态方法是与类关联的,而不是与对象实例关联的。`this`关键字用于引用当前对象实例,而静态方法没有隐式的当前对象实例。静态方法的目的是在没有对象实例的情况下执行某些操作,因此无法使用`this`关键字引用当前对象。如果在静态方法中需要访问对象的成员变量或方法,应该通过参数传递对象实例或通过类名访问静态成员。
  • 查看全部(116条)

2024-06-24 23:20 郑如滨 集美大学 在Java程序设计课程中提问:

思考:对象的初始化

1.构造方法有什么用?一般在构造方法中编写什么代码? 2.如果一个类有多个构造方法,创建对象时怎么确定调用哪个? 3.任何一个类都有无参数构造方法吗?一个类不编写构造方法可以吗? 4.新建对象,初始化块先执行还是构造方法先执行? 5.为什么有构造方法可以进行初始化工作,还需要初始化块?

  • 2025-01-15 18:53 朱勋飞

    构造方法主要用于初始化对象的状态。它在对象创建时被自动调用,确保对象以一个合理且完整的状态被创建。一般在构造方法中编写代码来设置对象的属性,如给成员变量赋初值,执行对象状态的必要设置等。
    当一个类有多个构造方法时,创建对象时通过传递给构造函数的参数来确定调用哪个构造方法。Java会根据传递的参数类型和数量自动匹配最合适的构造方法。如果参数不匹配任何构造方法,编译器会报错。
    并非任何一个类都有无参数构造方法。如果一个类没有定义任何构造方法,Java编译器会自动为该类添加一个默认的无参数构造方法。但是一旦在类中定义了至少一个构造方法,编译器将不再提供默认的无参数构造方法。因此,一个类可以不编写构造方法,但前提是不定义任何自定义构造方法。
    在对象创建时,初始化块(无论是实例初始化块还是静态初始化块)的执行优先于构造方法。实例初始化块会在构造方法被调用之前执行,用于初始化对象的属性或执行一些预处理。这意味着,当一个对象被创建时,首先执行所有实例初始化块,然后才调用构造方法。
  • 查看全部(137条)

2024-06-24 23:14 郑如滨 集美大学 在Java程序设计课程中提问:

思考:循环的使用

1.一般来说什么时候使用for什么时候使用while?试举例说明 2.for循环与while循环可以相互转换吗?试举例说明 3.while(true){.........}与for(;;){.....}都是死循环,计算机会不断执行循环体中的东西。这样的代码有意义吗?试举例说明

  • 2025-01-15 18:53 朱勋飞

    1. for循环和while循环的使用场景

    • for循环

    • 当明确知道循环的次数时,通常使用for循环。例如,遍历一个数组,假设我们有一个整数数组nums = [1, 2, 3, 4, 5],要打印数组中的每个元素,就可以使用for循环。
    int[] nums = {1, 2, 3, 4, 5};
    for (int i = 0; i < nums.length; i++) {
    System.out.println(nums[i]);
    }
    • 这里循环的次数是数组的长度,在for循环的初始化部分(int i = 0)定义了循环变量,在条件判断部分(i < nums.length)确定了循环结束的条件,在每次循环后的更新部分(i++)对循环变量进行更新。

    • while循环

    • 当循环的次数不确定,而是由某个条件来决定是否继续循环时,使用while循环。例如,猜数字游戏,程序生成一个1到100之间的随机数,让用户猜测这个数字,直到猜对为止。
    import java.util.Random;
    import java.util.Scanner;

    public class GuessNumber {
    public static void main(String[] args) {
    Random random = new Random();
    int numberToGuess = random.nextInt(100) + 1;
    Scanner scanner = new Scanner(System.in);
    int userGuess;
    do {
    System.out.print("请输入你的猜测: ");
    userGuess = scanner.nextInt();
    if (userGuess > numberToGuess) {
    System.out.println("猜大了");
    } else if (userGuess < numberToGuess) {
    System.out.println("猜小了");
    }
    } while (userGuess!= numberToGuess);
    System.out.println("猜对了!");
    }
    }
    • 在这个例子中,我们不知道用户需要猜测多少次才能猜对数字,循环会一直执行,直到用户猜对(userGuess == numberToGuess这个条件不满足)。

    2. for循环和while循环的相互转换

    • for循环可以转换为while循环,以刚才遍历数组的例子来说,转换后的代码如下:
    int[] nums = {1, 2, 3, 4, 5};
    int i = 0;
    while (i < nums.length) {
    System.out.println(nums[i]);
    i++;
    }
    • 可以看到,把for循环的初始化部分放在while循环之前,for循环的条件判断部分放在while的条件判断位置,for循环每次循环后的更新部分放在while循环体内部。

    • 同样,while循环也可以转换为for循环。以猜数字游戏为例(简化后的代码,去掉了提示信息):
    import java.util.Random;
    import java.util.Scanner;

    public class GuessNumberInFor {
    public static void main(String[] args) {
    Random random = new Random();
    int numberToGuess = random.nextInt(100) + 1;
    Scanner scanner = new Scanner(System.in);
    for (int userGuess = scanner.nextInt(); userGuess!= numberToGuess; userGuess = scanner.nextInt()) {
    }
    System.out.println("猜对了!");
    }
    }
    • 在这里,把while循环的条件判断部分放在了for循环的条件判断位置,在for循环的初始化部分获取用户的第一次猜测,在每次循环后的更新部分获取用户的下一次猜测。

    3. while(true)和for(;;)死循环的意义

    • 这样的代码是有意义的。例如,在服务器程序中,服务器需要一直运行,等待客户端的连接请求。以一个简单的TCP服务器为例(以下是伪代码):
    while (true) {
    // 等待客户端连接
    Socket clientSocket = serverSocket.accept();
    // 处理客户端请求
    handleClientRequest(clientSocket);
    }
    • 或者使用for(;;)来实现同样的功能:
    for (;;) {
    // 等待客户端连接
    Socket clientSocket = serverSocket.accept();
    // 处理客户端请求
    handleClientRequest(clientSocket);
    }
    • 在这个例子中,服务器需要不断地监听客户端的连接请求,一旦有请求就进行处理。这种死循环结构可以保证服务器一直处于工作状态,直到手动停止服务器程序。另外,在一些游戏开发中,游戏的主循环也经常使用类似的死循环结构,来不断地更新游戏画面、处理用户输入等。
  • 查看全部(146条)

2024-06-24 23:18 郑如滨 集美大学 在Java程序设计课程中提问:

思考:引用数据类型与基本数据类型的区别是什么?

分析如下代码,并回答如下4个问题: String str1 = new String("123"); String str2 = new String("123"); System.out.println(str1==str2);//1.输出什么?为什么? System.out.println

  • 2025-01-15 18:52 朱勋飞

    输出结果为false。这是因为str1和str2是两个不同的对象,虽然它们的值相同,但是它们在内存中的地址不同。使用==比较的是两个对象的引用是否相同。
    输出结果为true。这是因为String类重写了equals()方法,用于比较字符串的内容是否相同。在这个例子中,str1和str2的内容都是"123",所以equals()方法返回true。
    输出结果为true。这是因为x和y都是基本数据类型的变量,它们直接存储了数值,而不是引用。因此,比较的是它们存储的数值是否相同。
    引用数据类型变量与基本数据类型变量的不同在于,引用数据类型变量存储的是对象的引用(内存地址),而基本数据类型变量直接存储数值。引用数据类型变量需要使用equals()方法来比较对象的内容,而基本数据类型变量可以直接使用==进行比较。此外,引用数据类型变量可以为null,表示未引用任何对象,而基本数据类型变量不可以为null。
  • 查看全部(135条)

2024-06-24 23:22 郑如滨 集美大学 在Java程序设计课程中提问:

练一练:设计一个Triangle三角形类与Shape形状类,并用UML类图进行描述

1.试设计一个三角形类继承自Shape类。这两个类分别具有什么属性?为什么要这这样设计? 2.可选:尝试使用UML类图绘制出继承关系,并截图分享。 参考资料 UML类图参考链接:http://www.cnblogs.com/doubleyan/archive/2009/11/21/21648

  • 2025-01-15 18:52 朱勋飞

    1. Shape 类:

    - 属性:可以有颜色属性,比如 color 。因为形状通常会有颜色这个特征,不同的形状可以有不同的颜色来区分。
    - 可能的方法:可以有一个获取颜色的方法 getColor() 。
    2. Triangle 类:

    - 属性:除了继承自 Shape 类的颜色属性外,还可以有三条边的长度属性,比如 side1 、 side2 、 side3 。因为三角形的主要特征就是三条边的长度,通过这三个属性可以确定一个特定的三角形。
    - 方法:可以有计算周长的方法 getPerimeter() 和计算面积的方法 getArea() 。
  • 查看全部(106条)

常见问题

  • 1.我该如何学习这门课程?

    (1)首先您要注册一个学银在线的账号。

    (2)您需要有一定的上网条件,能够流畅的观看教学视频。在观看的过程中,您可以选择在PC端登陆我们的网页, 也可以选择下载我们的app学习通,通过手机客户端来学习。

    (3)您一旦报名选择了课程,我们的课程主讲老师或课程团队会通过通知的形式给您发送课程有关的消息,同时会抄送您的邮箱,请您及时查收。

  • 2.我在学习过程中遇到问题了,怎么办?

    您可以通过以下几种方式获取帮助:

    (1)在课程群聊中发布求助信息,说不定和你一起学习这门课的小伙伴就能够解决你的问题呢;

    (2)在课程讨论区留言,课程团队看到后将会及时回复。

    (3)联系我们的客服,或者随时给我们发邮件,邮箱地址:xueyinkf@chaoxing.com。

  • 3.我是新手,能否给我一些学习建议?

    (1)我们的课程采用MOOC的方式授课,因此您可以自由安排您的学习时间、学习地点。但我们仍旧希望您每周能都有固定的时间持续进行本课程的学习,根据人的记忆曲线显示这种规律的学习方式能够最大限度的提升您的学习质量。

    (2)学习的过程比较容易,为了检验您的学习成果,我们的课程团队会在课程章节结束后布置测验或作业,希望您尽可能的按时独立完成。如果有没有掌握的知识点,您可以继续回看复习课程。

    (3)希望您能够积极参与课程的讨论,与各位学习者一起煮酒论英雄。在讨论的过程中,不光可以对课程所学内容温习内化,还能互相碰撞出思想的火花,相信您一定会有额外的收获。

  • 4.课程会不会很难、很枯燥?

    (1)我们的课程都是老师经过精心设计拍摄制作而成,并且由于是MOOC的方式,所以课程拆分成了不同的知识点,学习起来一点也不费劲。

    (2)我们的课程多采取理论结合实际的授课方式,课程中也有许多案例的呈现,相信会给学习者带来诸多方面的启发。我们也将力求做到深入浅出,支持学习者将研究发现转化为实践,改进自身教学。