內容目錄

Java Lab 5: ADTs (The Add comment Overview JobManager)

This lab activity focuses on the design and implementation of an abstract data type (ADT) that we shall call JobManager .

A JobManager is responsible to managing a set of jobs, which are identified by integer IDs from 1 to n .

A JobManager also maintains a set of Robot objects that are responsible for completing these jobs.

The JobManager ADT’s operations enable its user to manage the set of Robots and the assignment of jobs to those Robots.

Learning Goals

  • Develop proficiency in recognizing, reasoning about, and implementing ADTs, which includes:
    • Interpreting the specified operations for an ADT;
    • Classifying ADT operations by type

Robot.java

package jobmanager;

/**
 * This immutable class represents a real-world Robot, which has a unique positive integer id. A Null Robot, which can
 * be used to indicate the absence of a real-world Robot, has an id of 0.
 */

public final class Robot {

    private final static Robot nullRobot = new Robot();

    public final int id;

    /**
     * Creates a new real-world Robot with the specified id.
     *
     * @param id
     * @throws IllegalArgumentException if id <= 0
     */
    public Robot(int id)
    {
        if (id <= 0) { throw new IllegalArgumentException("Robot id must be strictly positive"); }
        this.id = id;
    }

    private Robot() { this.id = 0; }

    /**
     * Checks if this Robot is a Null Robot
     *
     * @return true iff this.id = 0
     */
    public boolean isNull() {
        return id == 0;
    }

    /**
     * Compares the specified object with this Robot for equality
     *
     * @param o
     * @return true iff this and o represent real-world Robots with the same id
     */
    @Override
    public boolean equals(Object o) {
        if (o == null || !(o instanceof Robot)) { return false; }
        Robot other = (Robot) o;
        return this.id == other.id;
    }

    /**
     * Returns the hashcode for this Robot
     *
     * @return the hashcode value which is the id of this
     */
    @Override
    public int hashCode() {
        return id;
    }

    /**
     * Returns a Null Robot
     *
     * @return a Robot instance with id = 0
     */
    public static Robot getNullRobot() { return Robot.nullRobot; }

}

Robot 類別說明(來自索引標籤)

📌 類別功能

  • 表示一個具有唯一正整數 ID 的機器人。
  • 提供一個特殊的「Null Robot」,其 ID 為 0,用來表示「沒有機器人」的情況。

🔍 方法與行為

方法 功能說明
Robot(int id) 建構子:建立一個真實機器人,ID 必須為正整數,否則丟出例外。
private Robot() 私有建構子:建立 Null Robot(ID 為 0)。
isNull() 判斷是否為 Null Robot。
equals(Object o) 比較兩個 Robot 是否相等(根據 ID)。
hashCode() 回傳機器人的雜湊碼(就是 ID)。
getNullRobot() 回傳 Null Robot 的單一實例。

🧠 設計特性

  • 不可變性idfinal,且類別本身是 final,確保物件建立後不可修改。
  • Null Object 模式:使用 Robot(0) 作為 Null Robot,避免使用 null 參考。
  • 相等性與雜湊一致性equals()hashCode() 根據 id 定義,適合用於集合類型如 HashSetHashMap

✅ 用法範例(中文註解)

Robot r1 = new Robot(5);           // 建立 ID 為 5 的機器人
Robot r2 = Robot.getNullRobot();   // 取得 Null Robot
System.out.println(r1.isNull());   // false
System.out.println(r2.isNull());   // true

Java 實驗五:抽象資料型別(ADT)— JobManager

這項實驗活動的重點是設計與實作一個名為 JobManager 的抽象資料型別(ADT)。

JobManager 的職責

  • 管理一組工作(jobs):每個工作由一個整數 ID 表示,範圍從 1n
  • 管理一組機器人(Robot)物件:這些機器人負責完成上述工作。
  • 提供操作方法:讓使用者能夠管理機器人集合,以及將工作分配給這些機器人。

學習目標(Learning Goals)

透過這次實驗,你將培養以下能力:

  • 熟練地辨識、推理與實作抽象資料型別(ADT),包括:
    • 解讀 ADT 的操作規格;
    • 將 ADT 的操作分類為以下幾種型別:
類型 說明
Creator(創建者) 建立新的 ADT 實例,例如建構子。
Producer(生產者) 產生新的資料或狀態,例如分配工作。
Observer(觀察者) 查詢目前狀態,例如檢查是否已分配工作。
Mutator(變異者) 修改現有狀態,例如新增或移除機器人。

Lab 5.1 Assessment overview Total points: 0/0 Score: 0% Question LB5.1.1 Total points: — Report an error in this question Previous question Next question Personal Notes No attached notes Attach a file Add text note

Lab 5:抽象資料型別(ADT)— JobManager

這次實驗的重點是設計並實作一個名為 JobManager 的抽象資料型別(ADT)。JobManager 的職責是管理一組工作(jobs),每個工作由一個整數 ID(從 1 到 n)識別。它同時也管理一組 Robot 物件,這些機器人負責完成這些工作。

🎯 學習目標

  • 熟悉 ADT 的設計與實作。
  • 能夠解讀 ADT 的操作規格。
  • 能夠將 ADT 的操作分類為:
    • 創建者(Creator)
    • 生產者(Producer)
    • 觀察者(Observer)
    • 變異者(Mutator)

⚙️ JobManager 的功能概述

方法 功能說明
JobManager(int n) 建立一個管理 n 個工作的 JobManager。
hasRobot(Robot robot) 檢查是否已管理指定的機器人。
addRobot(Robot robot) 將機器人加入管理。
removeRobot(Robot robot) 移除機器人並取消其所有工作分配。
assignJobs(Robot robot, int jobId) 將所有未分配且 ID ≤ jobId 的工作分配給指定機器人。
isAssigned(int jobId) 檢查某個工作是否已被分配。
getRobot(int jobId) 取得負責某個工作的機器人。
moveJobs(Robot src, Robot dst, int jobId) 將來源機器人中 ID ≤ jobId 的工作轉移給目標機器人。
moveJobs(Robot src, Robot dst) 將來源機器人的所有工作轉移給目標機器人。
getHighestPriorityJob(Robot robot, int jobId) 取得指定機器人中 ID ≤ jobId 的最高優先工作。
sameAs(JobManager o) 比較兩個 JobManager 是否在觀察上相等(機器人池、工作分配、未分配工作都相同)。

🤖 Robot 類別簡介

  • 每個 Robot 有唯一的正整數 ID。
  • Null Robot(ID 為 0)代表「沒有機器人」,不能被分配工作。
  • Robot 是不可變類別(immutable),支援相等性比較與 hashCode。

如果你想要我幫你翻譯某段具體的程式碼或說明文字,或是需要幫忙撰寫 JobManager.java 的實作,我也可以一步步帶你完成。你想先從哪個方法開始呢?

幫忙撰寫 JobManager.java 的實作,我也可以一步步帶你完成。

太好了,強!我們就一步步來實作 JobManager.java。這個類別的核心任務是管理工作(jobs)與機器人(robots)的分配。以下是我們的策略:

🧱 第一步:類別結構與欄位設計

我們需要追蹤:

  • 所有工作(job IDs)
  • 哪些工作已分配給哪個機器人
  • 哪些機器人正在被管理

java

package jobmanager;

import java.util.*;

public class JobManager {
    private final int maxJobId;
    private final Set<Robot> robots;
    private final Map<Integer, Robot> jobAssignments;

    public JobManager(int n) {
        if (n < 1) throw new IllegalArgumentException("Job count must be ≥ 1");
        this.maxJobId = n;
        this.robots = new HashSet<>();
        this.jobAssignments = new HashMap<>();
    }

🤖 第二步:機器人管理方法

hasRobot(Robot robot)

java

    public boolean hasRobot(Robot robot) {
        return robots.contains(robot);
    }

addRobot(Robot robot)

java

    public boolean addRobot(Robot robot) {
        if (robot == null || robot.isNull()) return false;
        return robots.add(robot);
    }

removeRobot(Robot robot)

java

    public boolean removeRobot(Robot robot) {
        if (!robots.remove(robot)) return false;
        for (Map.Entry<Integer, Robot> entry : jobAssignments.entrySet()) {
            if (entry.getValue().equals(robot)) {
                entry.setValue(Robot.getNullRobot());
            }
        }
        return true;
    }

📦 第三步:工作分配與查詢

assignJobs(Robot robot, int jobId)

java

    public boolean assignJobs(Robot robot, int jobId) {
        if (!hasRobot(robot) || jobId < 1 || jobId > maxJobId) return false;
        boolean assigned = false;
        for (int i = 1; i <= jobId; i++) {
            if (!jobAssignments.containsKey(i) || jobAssignments.get(i).isNull()) {
                jobAssignments.put(i, robot);
                assigned = true;
            }
        }
        return assigned;
    }

isAssigned(int jobId)

java

    public boolean isAssigned(int jobId) {
        return jobAssignments.containsKey(jobId) && !jobAssignments.get(jobId).isNull();
    }

getRobot(int jobId)

java

    public Robot getRobot(int jobId) {
        if (!jobAssignments.containsKey(jobId)) return Robot.getNullRobot();
        return jobAssignments.get(jobId);
    }

🔄 第四步:工作轉移與查詢優先工作

moveJobs(Robot src, Robot dst, int jobId)

java

    public boolean moveJobs(Robot src, Robot dst, int jobId) {
        if (!hasRobot(src) || !hasRobot(dst)) return false;
        boolean moved = false;
        for (int i = 1; i <= jobId; i++) {
            if (src.equals(jobAssignments.get(i))) {
                jobAssignments.put(i, dst);
                moved = true;
            }
        }
        return moved;
    }

moveJobs(Robot src, Robot dst)

java

    public boolean moveJobs(Robot src, Robot dst) {
        if (!hasRobot(src) || !hasRobot(dst)) return false;
        boolean moved = false;
        for (int i = 1; i <= maxJobId; i++) {
            if (src.equals(jobAssignments.get(i))) {
                jobAssignments.put(i, dst);
                moved = true;
            }
        }
        return moved;
    }

getHighestPriorityJob(Robot robot, int jobId)

java

    public int getHighestPriorityJob(Robot robot, int jobId) {
        if (!hasRobot(robot)) return 0;
        for (int i = jobId; i >= 1; i--) {
            if (robot.equals(jobAssignments.get(i))) {
                return i;
            }
        }
        return 0;
    }

🧪 第五步:觀察相等性

sameAs(JobManager o)

java

    public boolean sameAs(JobManager o) {
        if (this.maxJobId != o.maxJobId) return false;
        if (!this.robots.equals(o.robots)) return false;
        for (int i = 1; i <= maxJobId; i++) {
            Robot r1 = this.jobAssignments.getOrDefault(i, Robot.getNullRobot());
            Robot r2 = o.jobAssignments.getOrDefault(i, Robot.getNullRobot());
            if (!r1.equals(r2)) return false;
        }
        return true;
    }
}

這樣就完成了整個 JobManager 的實作!你想接下來一起撰寫測試案例嗎?還是要優化某個方法的邏輯?我可以幫你模擬幾個典型場景來驗證它的正確性。

實作 jobmanager.java

package jobmanager;

import java.util.*;

public class JobManager {
    // Maximum job ID managed by this JobManager
    private final int maxJobId;

    // Set of Robots currently managed
    private final Set<Robot> robotPool;

    // Mapping from job ID to assigned Robot
    private final Map<Integer, Robot> jobAssignments;

    /**
     * Constructs a JobManager to manage jobs with IDs from 1 to n.
     * @param n the number of jobs
     * @throws IllegalArgumentException if n < 1
     */
    public JobManager(int n) {
        if (n < 1) throw new IllegalArgumentException("Job count must be ≥ 1");
        this.maxJobId = n;
        this.robotPool = new HashSet<>();
        this.jobAssignments = new HashMap<>();
    }

    /**
     * Checks if the specified Robot is currently managed by this JobManager.
     * @param robot the Robot to check
     * @return true if robot is in the pool, false otherwise
     */
    public boolean hasRobot(Robot robot) {
        return robot != null && robotPool.contains(robot);
    }

    /**
     * Adds a Robot to the JobManager's pool.
     * @param robot the Robot to add
     * @return true if robot was not already present, false otherwise
     */
    public boolean addRobot(Robot robot) {
        if (robot == null || robot.isNull()) return false;
        return robotPool.add(robot);
    }

    /**
     * Removes a Robot from the pool and unassigns all jobs previously assigned to it.
     * @param robot the Robot to remove
     * @return true if robot was removed, false otherwise
     */
    public boolean removeRobot(Robot robot) {
        if (!robotPool.remove(robot)) return false;
        for (int i = 1; i <= maxJobId; i++) {
            if (robot.equals(jobAssignments.get(i))) {
                jobAssignments.put(i, Robot.getNullRobot());
            }
        }
        return true;
    }

    /**
     * Assigns all unassigned jobs with ID ≤ jobId to the specified Robot.
     * @param robot the Robot to assign jobs to
     * @param jobId the upper bound of job IDs to assign
     * @return true if any job was assigned, false otherwise
     */
    public boolean assignJobs(Robot robot, int jobId) {
        if (!hasRobot(robot) || jobId < 1 || jobId > maxJobId) return false;
        boolean changed = false;
        for (int i = 1; i <= jobId; i++) {
            Robot current = jobAssignments.getOrDefault(i, Robot.getNullRobot());
            if (current.isNull()) {
                jobAssignments.put(i, robot);
                changed = true;
            }
        }
        return changed;
    }

    /**
     * Checks if a job with the given ID is assigned to any Robot.
     * @param jobId the job ID to check
     * @return true if assigned, false otherwise
     */
    public boolean isAssigned(int jobId) {
        if (jobId < 1 || jobId > maxJobId) return false;
        Robot r = jobAssignments.getOrDefault(jobId, Robot.getNullRobot());
        return !r.isNull();
    }

    /**
     * Returns the Robot assigned to the specified job ID.
     * @param jobId the job ID
     * @return the assigned Robot, or Null Robot if unassigned or invalid
     */
    public Robot getRobot(int jobId) {
        if (jobId < 1 || jobId > maxJobId) return Robot.getNullRobot();
        return jobAssignments.getOrDefault(jobId, Robot.getNullRobot());
    }

    /**
     * Moves jobs with ID ≤ jobId from srcRobot to dstRobot.
     * @param srcRobot the source Robot
     * @param dstRobot the destination Robot
     * @param jobId the upper bound of job IDs to move
     * @return true if any job was moved, false otherwise
     */
    public boolean moveJobs(Robot srcRobot, Robot dstRobot, int jobId) {
        if (!hasRobot(srcRobot) || !hasRobot(dstRobot) || jobId < 1 || jobId > maxJobId) return false;
        boolean moved = false;
        for (int i = 1; i <= jobId; i++) {
            if (srcRobot.equals(jobAssignments.get(i))) {
                jobAssignments.put(i, dstRobot);
                moved = true;
            }
        }
        return moved;
    }

    /**
     * Moves all jobs from srcRobot to dstRobot.
     * @param srcRobot the source Robot
     * @param dstRobot the destination Robot
     * @return true if any job was moved, false otherwise
     */
    public boolean moveJobs(Robot srcRobot, Robot dstRobot) {
        if (!hasRobot(srcRobot) || !hasRobot(dstRobot)) return false;
        boolean moved = false;
        for (int i = 1; i <= maxJobId; i++) {
            if (srcRobot.equals(jobAssignments.get(i))) {
                jobAssignments.put(i, dstRobot);
                moved = true;
            }
        }
        return moved;
    }

    /**
     * Returns the highest priority job (largest ID ≤ jobId) assigned to the specified Robot.
     * @param robot the Robot to check
     * @param jobId the upper bound of job IDs
     * @return the highest priority job ID, or 0 if none found
     */
    public int getHighestPriorityJob(Robot robot, int jobId) {
        if (!hasRobot(robot) || jobId < 1 || jobId > maxJobId) return 0;
        for (int i = jobId; i >= 1; i--) {
            if (robot.equals(jobAssignments.get(i))) {
                return i;
            }
        }
        return 0;
    }

    /**
     * Checks if this JobManager is observationally equal to another.
     * @param o the other JobManager
     * @return true if both have same robot pool and identical job assignments
     */
    public boolean sameAs(JobManager o) {
        if (this.maxJobId != o.maxJobId) return false;
        if (!this.robotPool.equals(o.robotPool)) return false;
        for (int i = 1; i <= maxJobId; i++) {
            Robot r1 = this.jobAssignments.getOrDefault(i, Robot.getNullRobot());
            Robot r2 = o.jobAssignments.getOrDefault(i, Robot.getNullRobot());
            if (!r1.equals(r2)) return false;
        }
        return true;
    }
}

這份實作涵蓋了所有 Lab 5 所需的功能,並且:

  • 使用 HashSet 管理機器人池。
  • 使用 HashMap 管理工作分配。
  • 確保 Null Robot 不會被加入或分配。
  • 所有方法都符合 ADT 操作分類(Creator、Producer、Observer、Mutator)。

如果你想進一步撰寫測試案例、模擬使用情境,或優化某些邏輯,我也可以幫你設計 JobManagerTest.java。你想接下來做什麼?我們可以驗證 assign/move/sameAs 的行為是否正確。

JobManagerTest.java

package jobmanager;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class JobManagerTest {

    @Test
    public void testAddAndHasRobot() {
        JobManager jm = new JobManager(5);
        Robot r1 = new Robot(1);
        Robot r2 = new Robot(2);

        assertFalse(jm.hasRobot(r1));
        assertTrue(jm.addRobot(r1));
        assertTrue(jm.hasRobot(r1));
        assertFalse(jm.addRobot(r1)); // already added
        assertTrue(jm.addRobot(r2));
    }

    @Test
    public void testAssignJobs() {
        JobManager jm = new JobManager(5);
        Robot r1 = new Robot(1);
        jm.addRobot(r1);

        assertTrue(jm.assignJobs(r1, 3));
        assertTrue(jm.isAssigned(1));
        assertTrue(jm.isAssigned(2));
        assertTrue(jm.isAssigned(3));
        assertFalse(jm.isAssigned(4));
        assertEquals(r1, jm.getRobot(2));
    }

    @Test
    public void testRemoveRobot() {
        JobManager jm = new JobManager(5);
        Robot r1 = new Robot(1);
        jm.addRobot(r1);
        jm.assignJobs(r1, 5);

        assertTrue(jm.removeRobot(r1));
        assertFalse(jm.hasRobot(r1));
        assertFalse(jm.isAssigned(3));
        assertEquals(Robot.getNullRobot(), jm.getRobot(3));
    }

    @Test
    public void testMoveJobsWithLimit() {
        JobManager jm = new JobManager(5);
        Robot r1 = new Robot(1);
        Robot r2 = new Robot(2);
        jm.addRobot(r1);
        jm.addRobot(r2);
        jm.assignJobs(r1, 5);

        assertTrue(jm.moveJobs(r1, r2, 3));
        assertEquals(r2, jm.getRobot(1));
        assertEquals(r2, jm.getRobot(3));
        assertEquals(r1, jm.getRobot(4)); // not moved
    }

    @Test
    public void testMoveAllJobs() {
        JobManager jm = new JobManager(5);
        Robot r1 = new Robot(1);
        Robot r2 = new Robot(2);
        jm.addRobot(r1);
        jm.addRobot(r2);
        jm.assignJobs(r1, 5);

        assertTrue(jm.moveJobs(r1, r2));
        for (int i = 1; i <= 5; i++) {
            assertEquals(r2, jm.getRobot(i));
        }
    }

    @Test
    public void testHighestPriorityJob() {
        JobManager jm = new JobManager(5);
        Robot r1 = new Robot(1);
        jm.addRobot(r1);
        jm.assignJobs(r1, 4);

        assertEquals(4, jm.getHighestPriorityJob(r1, 5));
        assertEquals(3, jm.getHighestPriorityJob(r1, 3));
        assertEquals(0, jm.getHighestPriorityJob(r1, 0));
    }

    @Test
    public void testSameAs() {
        JobManager jm1 = new JobManager(5);
        JobManager jm2 = new JobManager(5);
        Robot r1 = new Robot(1);
        Robot r2 = new Robot(2);

        jm1.addRobot(r1);
        jm1.addRobot(r2);
        jm1.assignJobs(r1, 3);
        jm1.assignJobs(r2, 5);

        jm2.addRobot(r1);
        jm2.addRobot(r2);
        jm2.assignJobs(r1, 3);
        jm2.assignJobs(r2, 5);

        assertTrue(jm1.sameAs(jm2));
    }
}

🧪 測試涵蓋重點

  • ✅ 機器人新增與查詢
  • ✅ 工作分配與查詢
  • ✅ 機器人移除後工作解除分配
  • ✅ 工作搬移(限制與全部)
  • ✅ 查詢最高優先工作
  • ✅ ADT 相等性判斷

這些測試可以直接在 IDE 中執行(如 IntelliJ 或 Eclipse),並使用 JUnit 5 的 @Test 標註來驗證每個方法的行為。你想要我幫你設計邊界測試(例如非法 jobId 或 Null Robot)嗎?還是要加入更多異常處理測試?我們可以讓這份測試更強韌。

package jobmanager;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class JobManagerTest {

    /**
     * Tests adding robots and verifying their presence.
     */
    @Test
    public void testAddAndHasRobot() {
        JobManager jm = new JobManager(5);
        Robot r1 = new Robot(1);
        Robot r2 = new Robot(2);

        assertFalse(jm.hasRobot(r1));
        assertTrue(jm.addRobot(r1));
        assertTrue(jm.hasRobot(r1));
        assertFalse(jm.addRobot(r1)); // Should not add duplicate
        assertTrue(jm.addRobot(r2));
    }

    /**
     * Tests assigning jobs to a robot and verifying job ownership.
     */
    @Test
    public void testAssignJobs() {
        JobManager jm = new JobManager(5);
        Robot r1 = new Robot(1);
        jm.addRobot(r1);

        assertTrue(jm.assignJobs(r1, 3));
        assertTrue(jm.isAssigned(1));
        assertTrue(jm.isAssigned(2));
        assertTrue(jm.isAssigned(3));
        assertFalse(jm.isAssigned(4));
        assertEquals(r1, jm.getRobot(2));
    }

    /**
     * Tests removing a robot and ensuring its jobs are unassigned.
     */
    @Test
    public void testRemoveRobot() {
        JobManager jm = new JobManager(5);
        Robot r1 = new Robot(1);
        jm.addRobot(r1);
        jm.assignJobs(r1, 5);

        assertTrue(jm.removeRobot(r1));
        assertFalse(jm.hasRobot(r1));
        assertFalse(jm.isAssigned(3));
        assertEquals(Robot.getNullRobot(), jm.getRobot(3));
    }

    /**
     * Tests moving jobs up to a specific job ID from one robot to another.
     */
    @Test
    public void testMoveJobsWithLimit() {
        JobManager jm = new JobManager(5);
        Robot r1 = new Robot(1);
        Robot r2 = new Robot(2);
        jm.addRobot(r1);
        jm.addRobot(r2);
        jm.assignJobs(r1, 5);

        assertTrue(jm.moveJobs(r1, r2, 3));
        assertEquals(r2, jm.getRobot(1));
        assertEquals(r2, jm.getRobot(3));
        assertEquals(r1, jm.getRobot(4)); // Should remain with r1
    }

    /**
     * Tests moving all jobs from one robot to another.
     */
    @Test
    public void testMoveAllJobs() {
        JobManager jm = new JobManager(5);
        Robot r1 = new Robot(1);
        Robot r2 = new Robot(2);
        jm.addRobot(r1);
        jm.addRobot(r2);
        jm.assignJobs(r1, 5);

        assertTrue(jm.moveJobs(r1, r2));
        for (int i = 1; i <= 5; i++) {
            assertEquals(r2, jm.getRobot(i));
        }
    }

    /**
     * Tests retrieving the highest priority job assigned to a robot.
     */
    @Test
    public void testHighestPriorityJob() {
        JobManager jm = new JobManager(5);
        Robot r1 = new Robot(1);
        jm.addRobot(r1);
        jm.assignJobs(r1, 4);

        assertEquals(4, jm.getHighestPriorityJob(r1, 5));
        assertEquals(3, jm.getHighestPriorityJob(r1, 3));
        assertEquals(0, jm.getHighestPriorityJob(r1, 0)); // Invalid range
    }

    /**
     * Tests observational equality between two JobManager instances.
     */
    @Test
    public void testSameAs() {
        JobManager jm1 = new JobManager(5);
        JobManager jm2 = new JobManager(5);
        Robot r1 = new Robot(1);
        Robot r2 = new Robot(2);

        jm1.addRobot(r1);
        jm1.addRobot(r2);
        jm1.assignJobs(r1, 3);
        jm1.assignJobs(r2, 5);

        jm2.addRobot(r1);
        jm2.addRobot(r2);
        jm2.assignJobs(r1, 3);
        jm2.assignJobs(r2, 5);

        assertTrue(jm1.sameAs(jm2));
    }

    /**
     * Tests edge cases: null robot, invalid job ID, and duplicate removal.
     */
    @Test
    public void testEdgeCases() {
        JobManager jm = new JobManager(5);
        Robot r1 = new Robot(1);

        // Null robot should not be added
        assertFalse(jm.addRobot(Robot.getNullRobot()));

        // Assigning jobs to unregistered robot should fail
        assertFalse(jm.assignJobs(r1, 3));

        // Adding then removing robot twice
        assertTrue(jm.addRobot(r1));
        assertTrue(jm.removeRobot(r1));
        assertFalse(jm.removeRobot(r1)); // Already removed

        // Invalid job ID queries
        assertFalse(jm.isAssigned(0));
        assertFalse(jm.isAssigned(6));
        assertEquals(Robot.getNullRobot(), jm.getRobot(0));
        assertEquals(Robot.getNullRobot(), jm.getRobot(6));
    }
}
最後修改日期: 2025 年 10 月 13 日

作者

留言

撰寫回覆或留言

發佈留言必須填寫的電子郵件地址不會公開。